- Notifications
You must be signed in to change notification settings - Fork425
Description
cpp-netlib callsboost::promise::set_exception() with astd::exception_ptr as argument in a number of places (for example, inhttp_async_connection::handle_received_data().
boost::promise::set_exception() has two overloads:
voidset_exception(boost::exception_ptr e);template<typename E>voidset_exception(E e);
The first overload takes aboost::exception_ptr (note:notstd::exception_ptr) wrapping a concrete exception. The second overload accepts a concrete exception object itself (and internally wraps it inboost::exception_ptr).
Whenset_exception() is called with an argument of typestd::exception_ptr, the second overload is matched, soboost::promise treatsstd::exception_ptr as the concrete exception type.
The reason this is a problem (besides the inefficiency of wrapping an exception in two layers of exception pointers), is that when the other side (future::get()) throws the exception, the thrown exception object will be thestd::exception_ptr itself, not the concrete exception object that it wraps.
For example, suppose the concrete exception type isboost::system::system_error (as is the case inhttp_async_connection::handle_received_data()). While the client code may be expecting to catch it with a catch clause like this:
catch (boost::system::system_error& e) { ...}in fact this catch clause will not be matched, because the thrown type wasstd::exception_ptr.
The fix is simple: when callingboost::promise::set_exception(), don't wrap the concrete exception type withstd::make_exception_ptr: just pass the concrete exception object directly.