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;
//]