AsyncSocketException: add detailed information in error message
authorBeny Luo <benyluo@fb.com>
Tue, 23 Feb 2016 17:44:14 +0000 (09:44 -0800)
committerfacebook-github-bot-0 <folly-bot@fb.com>
Tue, 23 Feb 2016 18:20:25 +0000 (10:20 -0800)
Summary: AsyncSocketException: add detailed information in error message

Reviewed By: yfeldblum

Differential Revision: D2953030

fb-gh-sync-id: a5e26036657ecc6c74ad0369650730a2af13bead
shipit-source-id: a5e26036657ecc6c74ad0369650730a2af13bead

folly/io/async/AsyncSocketException.h
folly/io/async/test/AsyncSocketExceptionTest.cpp [new file with mode: 0644]

index e49dcf1fc7f1f53e1ab61996477deb2bf9066f63..3113197c4b207b94208c1c3500ea958883bb81fb 100644 (file)
@@ -40,10 +40,13 @@ class AsyncSocketException : public std::runtime_error {
   , SASL_HANDSHAKE_TIMEOUT = 14
   };
 
-  AsyncSocketException(
-    AsyncSocketExceptionType type, const std::string& message) :
-      std::runtime_error(message),
-      type_(type), errno_(0) {}
+  AsyncSocketException(AsyncSocketExceptionType type,
+                       const std::string& message,
+                       int errno_copy = 0)
+      : std::runtime_error(
+            AsyncSocketException::getMessage(type, message, errno_copy)),
+        type_(type),
+        errno_(errno_copy) {}
 
   /** Error code */
   AsyncSocketExceptionType type_;
@@ -51,28 +54,67 @@ class AsyncSocketException : public std::runtime_error {
   /** A copy of the errno. */
   int errno_;
 
-  AsyncSocketException(AsyncSocketExceptionType type,
-                      const std::string& message,
-                      int errno_copy) :
-      std::runtime_error(getMessage(message, errno_copy)),
-      type_(type), errno_(errno_copy) {}
-
   AsyncSocketExceptionType getType() const noexcept { return type_; }
   int getErrno() const noexcept { return errno_; }
 
  protected:
   /** Just like strerror_r but returns a C++ string object. */
-  std::string strerror_s(int errno_copy) {
-    return "errno = " + folly::to<std::string>(errno_copy);
+  static std::string strerror_s(int errno_copy) {
+    return folly::sformat("errno = {} ({})", errno_copy, strerror(errno_copy));
+  }
+
+  /** get the string of exception type */
+  static folly::StringPiece getExceptionTypeString(
+      AsyncSocketExceptionType type) {
+    switch (type) {
+      case UNKNOWN:
+        return "Unknown async socket exception";
+      case NOT_OPEN:
+        return "Socket not open";
+      case ALREADY_OPEN:
+        return "Socket already open";
+      case TIMED_OUT:
+        return "Timed out";
+      case END_OF_FILE:
+        return "End of file";
+      case INTERRUPTED:
+        return "Interrupted";
+      case BAD_ARGS:
+        return "Invalid arguments";
+      case CORRUPTED_DATA:
+        return "Corrupted Data";
+      case INTERNAL_ERROR:
+        return "Internal error";
+      case NOT_SUPPORTED:
+        return "Not supported";
+      case INVALID_STATE:
+        return "Invalid state";
+      case SSL_ERROR:
+        return "SSL error";
+      case COULD_NOT_BIND:
+        return "Could not bind";
+      case SASL_HANDSHAKE_TIMEOUT:
+        return "SASL handshake timeout";
+      default:
+        return "(Invalid exception type)";
+    }
   }
 
   /** Return a message based on the input. */
-  std::string getMessage(const std::string &message,
+  static std::string getMessage(AsyncSocketExceptionType type,
+                                const std::string& message,
                                 int errno_copy) {
     if (errno_copy != 0) {
-      return message + ": " + strerror_s(errno_copy);
+      return folly::sformat(
+          "AsyncSocketException: {}, type = {}, errno = {} ({})",
+          message,
+          AsyncSocketException::getExceptionTypeString(type),
+          errno_copy,
+          strerror(errno_copy));
     } else {
-      return message;
+      return folly::sformat("AsyncSocketException: {}, type = {}",
+                            message,
+                            AsyncSocketException::getExceptionTypeString(type));
     }
   }
 };
diff --git a/folly/io/async/test/AsyncSocketExceptionTest.cpp b/folly/io/async/test/AsyncSocketExceptionTest.cpp
new file mode 100644 (file)
index 0000000..662a373
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2016 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <gtest/gtest.h>
+#include <folly/io/async/AsyncSocketException.h>
+
+using namespace testing;
+
+namespace folly {
+
+TEST(AsyncSocketException, SimpleTest) {
+  AsyncSocketException ex1(
+      AsyncSocketException::AsyncSocketExceptionType::NOT_OPEN,
+      "test exception 1");
+
+  EXPECT_EQ(AsyncSocketException::AsyncSocketExceptionType::NOT_OPEN,
+            ex1.getType());
+  EXPECT_EQ(0, ex1.getErrno());
+  EXPECT_EQ("AsyncSocketException: test exception 1, type = Socket not open",
+            std::string(ex1.what()));
+
+  AsyncSocketException ex2(
+      AsyncSocketException::AsyncSocketExceptionType::BAD_ARGS,
+      "test exception 2",
+      111 /*ECONNREFUSED*/);
+
+  EXPECT_EQ(AsyncSocketException::AsyncSocketExceptionType::BAD_ARGS,
+            ex2.getType());
+  EXPECT_EQ(111, ex2.getErrno());
+  EXPECT_EQ(
+      "AsyncSocketException: test exception 2, type = Invalid arguments, "
+      "errno = 111 (Connection refused)",
+      std::string(ex2.what()));
+}
+
+} // namespace folly