From cfde28c3c3cdf2e265743914d3bf2c13bcb45f76 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Wed, 2 Nov 2016 16:02:43 -0400 Subject: [PATCH] Add file and line number to thrown exceptions --- include/beast/core/detail/buffer_cat.hpp | 9 +++++--- include/beast/core/detail/type_traits.hpp | 14 ++++++++++++ include/beast/core/impl/basic_streambuf.ipp | 4 ++-- include/beast/core/impl/buffers_adapter.ipp | 5 +++-- include/beast/core/impl/static_streambuf.ipp | 4 +++- include/beast/core/static_string.hpp | 22 +++++++++++++------ include/beast/http/impl/message.ipp | 18 ++++++++------- include/beast/websocket/impl/stream.ipp | 1 + include/beast/websocket/option.hpp | 10 +++++++-- include/beast/zlib/detail/deflate_stream.hpp | 12 +++++++--- include/beast/zlib/detail/inflate_stream.hpp | 11 ++++++---- .../websocket/websocket_async_echo_server.hpp | 4 ++-- 12 files changed, 80 insertions(+), 34 deletions(-) diff --git a/include/beast/core/detail/buffer_cat.hpp b/include/beast/core/detail/buffer_cat.hpp index fdf2b610..b94d9965 100644 --- a/include/beast/core/detail/buffer_cat.hpp +++ b/include/beast/core/detail/buffer_cat.hpp @@ -253,7 +253,8 @@ private: reference dereference(C const&) const { - throw std::logic_error("invalid iterator"); + throw detail::make_exception( + "invalid iterator", __FILE__, __LINE__); } template @@ -269,7 +270,8 @@ private: void increment(C const&) { - throw std::logic_error("invalid iterator"); + throw detail::make_exception( + "invalid iterator", __FILE__, __LINE__); } template @@ -310,7 +312,8 @@ private: --iter(); return; } - throw std::logic_error("invalid iterator"); + throw detail::make_exception( + "invalid iterator", __FILE__, __LINE__); } template diff --git a/include/beast/core/detail/type_traits.hpp b/include/beast/core/detail/type_traits.hpp index 24928abd..f50b3a3c 100644 --- a/include/beast/core/detail/type_traits.hpp +++ b/include/beast/core/detail/type_traits.hpp @@ -10,6 +10,8 @@ #include #include +#include +#include namespace beast { namespace detail { @@ -78,6 +80,18 @@ struct repeat_tuple<0, T> using type = std::tuple<>; }; +template +Exception +make_exception(char const* reason, char const* file, int line) +{ + char const* n = file; + for(auto p = file; *p; ++p) + if(*p == '\\' || *p == '/') + n = p + 1; + return Exception{std::string(reason) + " (" + + n + ":" + std::to_string(line) + ")"}; +} + } // detail } // beast diff --git a/include/beast/core/impl/basic_streambuf.ipp b/include/beast/core/impl/basic_streambuf.ipp index c70d646b..a3fdcef7 100644 --- a/include/beast/core/impl/basic_streambuf.ipp +++ b/include/beast/core/impl/basic_streambuf.ipp @@ -524,8 +524,8 @@ basic_streambuf::basic_streambuf( , alloc_size_(alloc_size) { if(alloc_size <= 0) - throw std::invalid_argument( - "basic_streambuf: invalid alloc_size"); + throw detail::make_exception( + "invalid alloc_size", __FILE__, __LINE__); } template diff --git a/include/beast/core/impl/buffers_adapter.ipp b/include/beast/core/impl/buffers_adapter.ipp index cf537d6e..309830f1 100644 --- a/include/beast/core/impl/buffers_adapter.ipp +++ b/include/beast/core/impl/buffers_adapter.ipp @@ -8,6 +8,7 @@ #ifndef BEAST_IMPL_BUFFERS_ADAPTER_IPP #define BEAST_IMPL_BUFFERS_ADAPTER_IPP +#include #include #include #include @@ -413,8 +414,8 @@ buffers_adapter::prepare(std::size_t n) -> } } if(n > 0) - throw std::length_error( - "no space in buffers_adapter"); + throw detail::make_exception( + "no space", __FILE__, __LINE__); return mutable_buffers_type{*this}; } diff --git a/include/beast/core/impl/static_streambuf.ipp b/include/beast/core/impl/static_streambuf.ipp index 3f19cd7e..44c4e261 100644 --- a/include/beast/core/impl/static_streambuf.ipp +++ b/include/beast/core/impl/static_streambuf.ipp @@ -8,6 +8,7 @@ #ifndef BEAST_IMPL_STATIC_STREAMBUF_IPP #define BEAST_IMPL_STATIC_STREAMBUF_IPP +#include #include #include #include @@ -295,7 +296,8 @@ static_streambuf::prepare(std::size_t n) -> mutable_buffers_type { if(n > static_cast(end_ - out_)) - throw std::length_error("no space in streambuf"); + throw detail::make_exception( + "no space in streambuf", __FILE__, __LINE__); last_ = out_ + n; return mutable_buffers_type{out_, n}; } diff --git a/include/beast/core/static_string.hpp b/include/beast/core/static_string.hpp index a3ec8919..6a9ef1e6 100644 --- a/include/beast/core/static_string.hpp +++ b/include/beast/core/static_string.hpp @@ -8,6 +8,7 @@ #ifndef BEAST_WEBSOCKET_STATIC_STRING_HPP #define BEAST_WEBSOCKET_STATIC_STRING_HPP +#include #include #include #include @@ -329,7 +330,8 @@ static_string:: static_string(static_string const& s) { if(s.size() > N) - throw std::length_error("static_string overflow"); + throw detail::make_exception( + "static_string overflow", __FILE__, __LINE__); n_ = s.size(); Traits::copy(&s_[0], &s.s_[0], n_ + 1); } @@ -353,7 +355,8 @@ operator=(static_string const& s) -> static_string& { if(s.size() > N) - throw std::length_error("static_string overflow"); + throw detail::make_exception( + "static_string overflow", __FILE__, __LINE__); n_ = s.size(); Traits::copy(&s_[0], &s.s_[0], n_ + 1); return *this; @@ -391,7 +394,8 @@ at(size_type pos) -> reference { if(pos >= n_) - throw std::out_of_range("static_string::at"); + throw detail::make_exception( + "invalid pos", __FILE__, __LINE__); return s_[pos]; } @@ -402,7 +406,8 @@ at(size_type pos) const -> const_reference { if(pos >= n_) - throw std::out_of_range("static_string::at"); + throw detail::make_exception( + "static_string::at", __FILE__, __LINE__); return s_[pos]; } @@ -412,7 +417,8 @@ static_string:: resize(std::size_t n) { if(n > N) - throw std::length_error("static_string overflow"); + throw detail::make_exception( + "static_string overflow", __FILE__, __LINE__); n_ = n; s_[n_] = 0; } @@ -423,7 +429,8 @@ static_string:: resize(std::size_t n, CharT c) { if(n > N) - throw std::length_error("static_string overflow"); + throw detail::make_exception( + "static_string overflow", __FILE__, __LINE__); if(n > n_) Traits::assign(&s_[n_], n - n_, c); n_ = n; @@ -462,7 +469,8 @@ assign(CharT const* s) { auto const n = Traits::length(s); if(n > N) - throw std::out_of_range("too large"); + throw detail::make_exception( + "too large", __FILE__, __LINE__); n_ = n; Traits::copy(&s_[0], s, n_ + 1); } diff --git a/include/beast/http/impl/message.ipp b/include/beast/http/impl/message.ipp index 9a818cd8..3f7c0565 100644 --- a/include/beast/http/impl/message.ipp +++ b/include/beast/http/impl/message.ipp @@ -159,6 +159,8 @@ void prepare(message& msg, Options&&... options) { + using beast::detail::make_exception; + // VFALCO TODO static_assert(is_Body::value, "Body requirements not met"); @@ -174,16 +176,16 @@ prepare(message& msg, std::forward(options)...); if(msg.fields.exists("Connection")) - throw std::invalid_argument( - "prepare called with Connection field set"); + throw make_exception( + "prepare called with Connection field set", __FILE__, __LINE__); if(msg.fields.exists("Content-Length")) - throw std::invalid_argument( - "prepare called with Content-Length field set"); + throw make_exception( + "prepare called with Content-Length field set", __FILE__, __LINE__); if(token_list{msg.fields["Transfer-Encoding"]}.exists("chunked")) - throw std::invalid_argument( - "prepare called with Transfer-Encoding: chunked set"); + throw make_exception( + "prepare called with Transfer-Encoding: chunked set", __FILE__, __LINE__); if(pi.connection_value != connection::upgrade) { @@ -254,8 +256,8 @@ prepare(message& msg, // rfc7230 6.7. if(msg.version < 11 && token_list{ msg.fields["Connection"]}.exists("upgrade")) - throw std::invalid_argument( - "invalid version for Connection: upgrade"); + throw make_exception( + "invalid version for Connection: upgrade", __FILE__, __LINE__); } } // http diff --git a/include/beast/websocket/impl/stream.ipp b/include/beast/websocket/impl/stream.ipp index bd04db45..2e419249 100644 --- a/include/beast/websocket/impl/stream.ipp +++ b/include/beast/websocket/impl/stream.ipp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/include/beast/websocket/option.hpp b/include/beast/websocket/option.hpp index d2864cdd..4f009f96 100644 --- a/include/beast/websocket/option.hpp +++ b/include/beast/websocket/option.hpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -186,7 +187,8 @@ struct message_type message_type(opcode op) { if(op != opcode::binary && op != opcode::text) - throw std::domain_error("bad opcode"); + throw beast::detail::make_exception( + "bad opcode", __FILE__, __LINE__); value = op; } }; @@ -277,6 +279,9 @@ struct read_buffer_size read_buffer_size(std::size_t n) : value(n) { + if(n < 8) + throw beast::detail::make_exception( + "read buffer size is too small", __FILE__, __LINE__); } }; #endif @@ -356,7 +361,8 @@ struct write_buffer_size : value(n) { if(n < 8) - throw std::domain_error("write buffer size is too small"); + throw beast::detail::make_exception( + "write buffer size is too small", __FILE__, __LINE__); } }; #endif diff --git a/include/beast/zlib/detail/deflate_stream.hpp b/include/beast/zlib/detail/deflate_stream.hpp index 7b367d3e..45dbdb98 100644 --- a/include/beast/zlib/detail/deflate_stream.hpp +++ b/include/beast/zlib/detail/deflate_stream.hpp @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -893,14 +894,19 @@ doReset( if(windowBits == 8) windowBits = 9; + using beast::detail::make_exception; + if(level < 0 || level > 9) - throw std::invalid_argument{"invalid level"}; + throw make_exception( + "invalid level", __FILE__, __LINE__); if(windowBits < 8 || windowBits > 15) - throw std::invalid_argument{"invalid windowBits"}; + throw make_exception( + "invalid windowBits", __FILE__, __LINE__); if(memLevel < 1 || memLevel > MAX_MEM_LEVEL) - throw std::invalid_argument{"invalid memLevel"}; + throw make_exception( + "invalid memLevel", __FILE__, __LINE__); w_bits_ = windowBits; diff --git a/include/beast/zlib/detail/inflate_stream.hpp b/include/beast/zlib/detail/inflate_stream.hpp index c13d9428..5b748fbe 100644 --- a/include/beast/zlib/detail/inflate_stream.hpp +++ b/include/beast/zlib/detail/inflate_stream.hpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -232,7 +233,8 @@ inflate_stream:: doReset(int windowBits) { if(windowBits < 8 || windowBits > 15) - throw std::domain_error("windowBits out of range"); + throw beast::detail::make_exception( + "windowBits out of range", __FILE__, __LINE__); w_.reset(windowBits); bi_.flush(); @@ -706,7 +708,8 @@ doWrite(z_params& zs, Flush flush, error_code& ec) case SYNC: default: - throw std::logic_error("stream error"); + throw beast::detail::make_exception( + "stream error", __FILE__, __LINE__); } } } @@ -932,8 +935,8 @@ inflate_table( auto const not_enough = [] { - throw std::logic_error( - "insufficient output size when inflating tables"); + throw beast::detail::make_exception( + "insufficient output size when inflating tables", __FILE__, __LINE__); }; // check available table space diff --git a/test/websocket/websocket_async_echo_server.hpp b/test/websocket/websocket_async_echo_server.hpp index 07e1445b..8954eb55 100644 --- a/test/websocket/websocket_async_echo_server.hpp +++ b/test/websocket/websocket_async_echo_server.hpp @@ -160,8 +160,8 @@ private: auto& d = *d_; d.ws.set_option(decorate(identity{})); d.ws.set_option(read_message_max(64 * 1024 * 1024)); - d.ws.set_option(auto_fragment{false}); - d.ws.set_option(write_buffer_size{64 * 1024}); + //d.ws.set_option(auto_fragment{false}); + //d.ws.set_option(write_buffer_size{64 * 1024}); run(); }