85054d867ef192c7bd07253b405786769e996fc6
[folly.git] / folly / io / async / AsyncSocketException.h
1 /*
2  * Copyright 2016 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <folly/Format.h>
20 #include <folly/io/async/DelayedDestruction.h>
21
22 namespace folly {
23
24 class AsyncSocketException : public std::runtime_error {
25  public:
26   enum AsyncSocketExceptionType {
27     UNKNOWN = 0,
28     NOT_OPEN = 1,
29     ALREADY_OPEN = 2,
30     TIMED_OUT = 3,
31     END_OF_FILE = 4,
32     INTERRUPTED = 5,
33     BAD_ARGS = 6,
34     CORRUPTED_DATA = 7,
35     INTERNAL_ERROR = 8,
36     NOT_SUPPORTED = 9,
37     INVALID_STATE = 10,
38     SSL_ERROR = 12,
39     COULD_NOT_BIND = 13,
40     SASL_HANDSHAKE_TIMEOUT = 14,
41     NETWORK_ERROR = 15
42   };
43
44   AsyncSocketException(AsyncSocketExceptionType type,
45                        const std::string& message,
46                        int errno_copy = 0)
47       : std::runtime_error(
48             AsyncSocketException::getMessage(type, message, errno_copy)),
49         type_(type),
50         errno_(errno_copy) {}
51
52   /** Error code */
53   AsyncSocketExceptionType type_;
54
55   /** A copy of the errno. */
56   int errno_;
57
58   AsyncSocketExceptionType getType() const noexcept { return type_; }
59   int getErrno() const noexcept { return errno_; }
60
61  protected:
62   /** Just like strerror_r but returns a C++ string object. */
63   static std::string strerror_s(int errno_copy) {
64     return folly::sformat("errno = {} ({})", errno_copy, strerror(errno_copy));
65   }
66
67   /** get the string of exception type */
68   static folly::StringPiece getExceptionTypeString(
69       AsyncSocketExceptionType type) {
70     switch (type) {
71       case UNKNOWN:
72         return "Unknown async socket exception";
73       case NOT_OPEN:
74         return "Socket not open";
75       case ALREADY_OPEN:
76         return "Socket already open";
77       case TIMED_OUT:
78         return "Timed out";
79       case END_OF_FILE:
80         return "End of file";
81       case INTERRUPTED:
82         return "Interrupted";
83       case BAD_ARGS:
84         return "Invalid arguments";
85       case CORRUPTED_DATA:
86         return "Corrupted Data";
87       case INTERNAL_ERROR:
88         return "Internal error";
89       case NOT_SUPPORTED:
90         return "Not supported";
91       case INVALID_STATE:
92         return "Invalid state";
93       case SSL_ERROR:
94         return "SSL error";
95       case COULD_NOT_BIND:
96         return "Could not bind";
97       case SASL_HANDSHAKE_TIMEOUT:
98         return "SASL handshake timeout";
99       default:
100         return "(Invalid exception type)";
101     }
102   }
103
104   /** Return a message based on the input. */
105   static std::string getMessage(AsyncSocketExceptionType type,
106                                 const std::string& message,
107                                 int errno_copy) {
108     if (errno_copy != 0) {
109       return folly::sformat(
110           "AsyncSocketException: {}, type = {}, errno = {} ({})",
111           message,
112           AsyncSocketException::getExceptionTypeString(type),
113           errno_copy,
114           strerror(errno_copy));
115     } else {
116       return folly::sformat("AsyncSocketException: {}, type = {}",
117                             message,
118                             AsyncSocketException::getExceptionTypeString(type));
119     }
120   }
121 };
122
123 } // folly