Add AsyncSocketExceptionType for early data rejection.
[folly.git] / folly / io / async / AsyncSocketException.h
index f18bfed9f1f0f5aa17c5e3baaeb9f42e058c723e..19aecd2f4d52a9255b17d451f1fddae9c21ed892 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2017 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <stdexcept>
+
 #include <folly/Format.h>
 #include <folly/io/async/DelayedDestruction.h>
 
@@ -23,27 +25,32 @@ namespace folly {
 
 class AsyncSocketException : public std::runtime_error {
  public:
-  enum AsyncSocketExceptionType
-  { UNKNOWN = 0
-  , NOT_OPEN = 1
-  , ALREADY_OPEN = 2
-  , TIMED_OUT = 3
-  , END_OF_FILE = 4
-  , INTERRUPTED = 5
-  , BAD_ARGS = 6
-  , CORRUPTED_DATA = 7
-  , INTERNAL_ERROR = 8
-  , NOT_SUPPORTED = 9
-  , INVALID_STATE = 10
-  , SSL_ERROR = 12
-  , COULD_NOT_BIND = 13
-  , SASL_HANDSHAKE_TIMEOUT = 14
+  enum AsyncSocketExceptionType {
+    UNKNOWN = 0,
+    NOT_OPEN = 1,
+    ALREADY_OPEN = 2,
+    TIMED_OUT = 3,
+    END_OF_FILE = 4,
+    INTERRUPTED = 5,
+    BAD_ARGS = 6,
+    CORRUPTED_DATA = 7,
+    INTERNAL_ERROR = 8,
+    NOT_SUPPORTED = 9,
+    INVALID_STATE = 10,
+    SSL_ERROR = 12,
+    COULD_NOT_BIND = 13,
+    SASL_HANDSHAKE_TIMEOUT = 14,
+    NETWORK_ERROR = 15,
+    EARLY_DATA_REJECTED = 16,
   };
 
-  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,30 +58,73 @@ 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";
+      case NETWORK_ERROR:
+        return "Network error";
+      case EARLY_DATA_REJECTED:
+        return "Early data rejected";
+      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));
     }
   }
 };
 
-} // folly
+} // namespace folly