From: Beny Luo Date: Tue, 23 Feb 2016 17:44:14 +0000 (-0800) Subject: AsyncSocketException: add detailed information in error message X-Git-Tag: deprecate-dynamic-initializer~47 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=787e185c7cdc7f102a32711704b0a2a53d7f3e6e;p=folly.git AsyncSocketException: add detailed information in error message Summary: AsyncSocketException: add detailed information in error message Reviewed By: yfeldblum Differential Revision: D2953030 fb-gh-sync-id: a5e26036657ecc6c74ad0369650730a2af13bead shipit-source-id: a5e26036657ecc6c74ad0369650730a2af13bead --- diff --git a/folly/io/async/AsyncSocketException.h b/folly/io/async/AsyncSocketException.h index e49dcf1f..3113197c 100644 --- a/folly/io/async/AsyncSocketException.h +++ b/folly/io/async/AsyncSocketException.h @@ -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(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 index 00000000..662a3737 --- /dev/null +++ b/folly/io/async/test/AsyncSocketExceptionTest.cpp @@ -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 +#include + +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