3113197c4b207b94208c1c3500ea958883bb81fb
[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   };
42
43   AsyncSocketException(AsyncSocketExceptionType type,
44                        const std::string& message,
45                        int errno_copy = 0)
46       : std::runtime_error(
47             AsyncSocketException::getMessage(type, message, errno_copy)),
48         type_(type),
49         errno_(errno_copy) {}
50
51   /** Error code */
52   AsyncSocketExceptionType type_;
53
54   /** A copy of the errno. */
55   int errno_;
56
57   AsyncSocketExceptionType getType() const noexcept { return type_; }
58   int getErrno() const noexcept { return errno_; }
59
60  protected:
61   /** Just like strerror_r but returns a C++ string object. */
62   static std::string strerror_s(int errno_copy) {
63     return folly::sformat("errno = {} ({})", errno_copy, strerror(errno_copy));
64   }
65
66   /** get the string of exception type */
67   static folly::StringPiece getExceptionTypeString(
68       AsyncSocketExceptionType type) {
69     switch (type) {
70       case UNKNOWN:
71         return "Unknown async socket exception";
72       case NOT_OPEN:
73         return "Socket not open";
74       case ALREADY_OPEN:
75         return "Socket already open";
76       case TIMED_OUT:
77         return "Timed out";
78       case END_OF_FILE:
79         return "End of file";
80       case INTERRUPTED:
81         return "Interrupted";
82       case BAD_ARGS:
83         return "Invalid arguments";
84       case CORRUPTED_DATA:
85         return "Corrupted Data";
86       case INTERNAL_ERROR:
87         return "Internal error";
88       case NOT_SUPPORTED:
89         return "Not supported";
90       case INVALID_STATE:
91         return "Invalid state";
92       case SSL_ERROR:
93         return "SSL error";
94       case COULD_NOT_BIND:
95         return "Could not bind";
96       case SASL_HANDSHAKE_TIMEOUT:
97         return "SASL handshake timeout";
98       default:
99         return "(Invalid exception type)";
100     }
101   }
102
103   /** Return a message based on the input. */
104   static std::string getMessage(AsyncSocketExceptionType type,
105                                 const std::string& message,
106                                 int errno_copy) {
107     if (errno_copy != 0) {
108       return folly::sformat(
109           "AsyncSocketException: {}, type = {}, errno = {} ({})",
110           message,
111           AsyncSocketException::getExceptionTypeString(type),
112           errno_copy,
113           strerror(errno_copy));
114     } else {
115       return folly::sformat("AsyncSocketException: {}, type = {}",
116                             message,
117                             AsyncSocketException::getExceptionTypeString(type));
118     }
119   }
120 };
121
122 } // folly