2033be05441d59bfa540dc0744a20af8c935f097
[folly.git] / folly / io / async / AsyncSocketException.h
1 /*
2  * Copyright 2017 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 <stdexcept>
20
21 #include <folly/Format.h>
22 #include <folly/io/async/DelayedDestruction.h>
23
24 namespace folly {
25
26 class AsyncSocketException : public std::runtime_error {
27  public:
28   enum AsyncSocketExceptionType {
29     UNKNOWN = 0,
30     NOT_OPEN = 1,
31     ALREADY_OPEN = 2,
32     TIMED_OUT = 3,
33     END_OF_FILE = 4,
34     INTERRUPTED = 5,
35     BAD_ARGS = 6,
36     CORRUPTED_DATA = 7,
37     INTERNAL_ERROR = 8,
38     NOT_SUPPORTED = 9,
39     INVALID_STATE = 10,
40     SSL_ERROR = 12,
41     COULD_NOT_BIND = 13,
42     SASL_HANDSHAKE_TIMEOUT = 14,
43     NETWORK_ERROR = 15
44   };
45
46   AsyncSocketException(AsyncSocketExceptionType type,
47                        const std::string& message,
48                        int errno_copy = 0)
49       : std::runtime_error(
50             AsyncSocketException::getMessage(type, message, errno_copy)),
51         type_(type),
52         errno_(errno_copy) {}
53
54   /** Error code */
55   AsyncSocketExceptionType type_;
56
57   /** A copy of the errno. */
58   int errno_;
59
60   AsyncSocketExceptionType getType() const noexcept { return type_; }
61   int getErrno() const noexcept { return errno_; }
62
63  protected:
64   /** Just like strerror_r but returns a C++ string object. */
65   static std::string strerror_s(int errno_copy) {
66     return folly::sformat("errno = {} ({})", errno_copy, strerror(errno_copy));
67   }
68
69   /** get the string of exception type */
70   static folly::StringPiece getExceptionTypeString(
71       AsyncSocketExceptionType type) {
72     switch (type) {
73       case UNKNOWN:
74         return "Unknown async socket exception";
75       case NOT_OPEN:
76         return "Socket not open";
77       case ALREADY_OPEN:
78         return "Socket already open";
79       case TIMED_OUT:
80         return "Timed out";
81       case END_OF_FILE:
82         return "End of file";
83       case INTERRUPTED:
84         return "Interrupted";
85       case BAD_ARGS:
86         return "Invalid arguments";
87       case CORRUPTED_DATA:
88         return "Corrupted Data";
89       case INTERNAL_ERROR:
90         return "Internal error";
91       case NOT_SUPPORTED:
92         return "Not supported";
93       case INVALID_STATE:
94         return "Invalid state";
95       case SSL_ERROR:
96         return "SSL error";
97       case COULD_NOT_BIND:
98         return "Could not bind";
99       case SASL_HANDSHAKE_TIMEOUT:
100         return "SASL handshake timeout";
101       case NETWORK_ERROR:
102         return "Network error";
103       default:
104         return "(Invalid exception type)";
105     }
106   }
107
108   /** Return a message based on the input. */
109   static std::string getMessage(AsyncSocketExceptionType type,
110                                 const std::string& message,
111                                 int errno_copy) {
112     if (errno_copy != 0) {
113       return folly::sformat(
114           "AsyncSocketException: {}, type = {}, errno = {} ({})",
115           message,
116           AsyncSocketException::getExceptionTypeString(type),
117           errno_copy,
118           strerror(errno_copy));
119     } else {
120       return folly::sformat("AsyncSocketException: {}, type = {}",
121                             message,
122                             AsyncSocketException::getExceptionTypeString(type));
123     }
124   }
125 };
126
127 } // folly