diff --git a/CHANGELOG.md b/CHANGELOG.md index 5e5be9ad..982bb314 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Version 201 * Decay bound arguments in handler wrapper parameters * Add bind_back_handler * Tidy up default-constructed iterators +* Add core errors and conditions -------------------------------------------------------------------------------- diff --git a/doc/qbk/quickref.xml b/doc/qbk/quickref.xml index 0d55e5b1..d097edda 100644 --- a/doc/qbk/quickref.xml +++ b/doc/qbk/quickref.xml @@ -231,6 +231,8 @@ Constants + condition + error file_mode diff --git a/include/boost/beast/core/error.hpp b/include/boost/beast/core/error.hpp index f034f7a4..492dcd1b 100644 --- a/include/boost/beast/core/error.hpp +++ b/include/boost/beast/core/error.hpp @@ -52,7 +52,34 @@ enum errc{}; namespace errc = boost::system::errc; #endif +//------------------------------------------------------------------------------ + +/// Error codes returned from library operations +enum class error +{ + /** The socket was closed due to a timeout + + This error indicates that a socket was closed due to a + a timeout detected during an operation. + + Error codes with this value will compare equal to @ref condition::timeout. + */ + timeout = 1 +}; + +/// Error conditions corresponding to sets of library error codes. +enum class condition +{ + /** The operation timed out + + This error indicates that an operation took took too long. + */ + timeout = 1 +}; + } // beast } // boost +#include + #endif diff --git a/include/boost/beast/core/impl/error.hpp b/include/boost/beast/core/impl/error.hpp new file mode 100644 index 00000000..83736823 --- /dev/null +++ b/include/boost/beast/core/impl/error.hpp @@ -0,0 +1,79 @@ +// +// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/beast +// + +#ifndef BOOST_BEAST_IMPL_ERROR_HPP +#define BOOST_BEAST_IMPL_ERROR_HPP + +#include + +namespace boost { +namespace system { +template<> +struct is_error_code_enum +{ + static bool const value = true; +}; + +template<> +struct is_error_condition_enum +{ + static bool const value = true; +}; + +} // system +} // boost + +namespace boost { +namespace beast { +namespace detail { + +class error_codes : public error_category +{ +public: + BOOST_BEAST_DECL + const char* + name() const noexcept override; + + BOOST_BEAST_DECL + std::string + message(int ev) const override; + + BOOST_BEAST_DECL + error_condition + default_error_condition(int ev) const noexcept override; +}; + +class error_conditions : public error_category +{ +public: + BOOST_BEAST_DECL + const char* + name() const noexcept override; + + BOOST_BEAST_DECL + std::string + message(int cv) const override; +}; + +} // detail + +BOOST_BEAST_DECL +error_code +make_error_code(error e); + +BOOST_BEAST_DECL +error_condition +make_error_condition(condition c); + +} // beast +} // boost + +#include + +#endif diff --git a/include/boost/beast/core/impl/error.ipp b/include/boost/beast/core/impl/error.ipp new file mode 100644 index 00000000..edce699f --- /dev/null +++ b/include/boost/beast/core/impl/error.ipp @@ -0,0 +1,92 @@ +// +// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com) +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// Official repository: https://github.com/boostorg/beast +// + +#ifndef BOOST_BEAST_IMPL_ERROR_IPP +#define BOOST_BEAST_IMPL_ERROR_IPP + +namespace boost { +namespace beast { + +namespace detail { + +const char* +error_codes:: +name() const noexcept +{ + return "boost.beast"; +} + +std::string +error_codes:: +message(int ev) const +{ + switch(static_cast(ev)) + { + default: + case error::timeout: return + "The socket was closed due to a timeout"; + } +} + +error_condition +error_codes:: +default_error_condition(int ev) const noexcept +{ + switch(static_cast(ev)) + { + default: +// return {ev, *this}; + case error::timeout: + return condition::timeout; + } +} + +//------------------------------------------------------------------------------ + +const char* +error_conditions:: +name() const noexcept +{ + return "boost.beast"; +} + +std::string +error_conditions:: +message(int cv) const +{ + switch(static_cast(cv)) + { + default: + case condition::timeout: + return "The operation timed out"; + } +} + +} // detail + +error_code +make_error_code(error e) +{ + static detail::error_codes const cat{}; + return error_code{static_cast< + std::underlying_type::type>(e), cat}; +} + +error_condition +make_error_condition(condition c) +{ + static detail::error_conditions const cat{}; + return error_condition{static_cast< + std::underlying_type::type>(c), cat}; +} + +} // beast +} // boost + +#endif diff --git a/test/beast/core/error.cpp b/test/beast/core/error.cpp index b41fd52d..915096e5 100644 --- a/test/beast/core/error.cpp +++ b/test/beast/core/error.cpp @@ -9,3 +9,47 @@ // Test that header file is self-contained. #include + +#include +#include + +namespace boost { +namespace beast { + +class error_test : public unit_test::suite +{ +public: + // no condition + void check(error e) + { + auto const ec = make_error_code(e); + ec.category().name(); + BEAST_EXPECT(! ec.message().empty()); + } + + void check(condition c, error e) + { + { + auto const ec = make_error_code(e); + BEAST_EXPECT(ec.category().name() != nullptr); + BEAST_EXPECT(! ec.message().empty()); + BEAST_EXPECT(ec == c); + } + { + auto ec = make_error_condition(c); + BEAST_EXPECT(ec.category().name() != nullptr); + BEAST_EXPECT(! ec.message().empty()); + BEAST_EXPECT(ec == c); + } + } + + void run() override + { + check(condition::timeout, error::timeout); + } +}; + +BEAST_DEFINE_TESTSUITE(beast,websocket,error); + +} // beast +} // boost diff --git a/test/doc/http_snippets.cpp b/test/doc/http_snippets.cpp index 53afcfab..1547de72 100644 --- a/test/doc/http_snippets.cpp +++ b/test/doc/http_snippets.cpp @@ -102,7 +102,7 @@ void fxx() { error_code ec; request req; read(sock, buffer, req, ec); - if(ec == error::buffer_overflow) + if(ec == http::error::buffer_overflow) std::cerr << "Buffer limit exceeded!" << std::endl; //]