
Gavin Lambert wrote:
To clarify, I was wondering if we should:
1. Implement an error-to-exception conversion trait as a generic template which does not compile by default. 2. Provide a specialisation for boost::system::error_code which returns boost::system::system_error. 3. (Where supported by the STL) Provide a specialisation for std::error_code which returns std::system_error. 4. Allow users to provide additional specialisations for other error types. 5. Provide generic boost::throw_error which calls boost::throw_exception on the result of the conversion trait. 6. Make Outcome's default policy call boost::throw_error instead of hard UB.
Looking at my various expected/result experiments, what I've done there is: - in expected<>, I call `throw_on_unexpected(e)` unqualified, and if that returns, I throw bad_expected_access<E>(e): https://github.com/pdimov/variant2/blob/81023c3569b3edcd9c5d631862905744e20c... https://github.com/pdimov/variant2/blob/81023c3569b3edcd9c5d631862905744e20c... - in (one) result<>, I call error_code_to_exception(e) unqualified, then throw the result: https://github.com/pdimov/result/blob/e7f0b076e267111098e49d8e7f7c15b5dbb7ca... https://github.com/pdimov/result/blob/e7f0b076e267111098e49d8e7f7c15b5dbb7ca... However, I vaguely remember that I convinced myself at one point that the latter (calling a function to convert) is inferior to calling a function that throws. For one thing, you can't convert an exception_ptr to an exception (*); for another, sometimes you want to throw different exceptions based on the runtime value of the error code (bad_alloc on ENOMEM for instance.) So I would probably go with calling `throw_exception_from_error_code(e)` unqualified nowadays. (And follow that call with __builtin_unreachable(), allowing diehard fans of undefined behavior to obtain it by returning.) (*) This is needed, for instance, when you build an outcome<> on top of a result<> by struct my_error_code { std::error_code code_; std::exception_ptr exc_; }; template<class T> using outcome = result<T, my_error_code>; Now you want something like this: void throw_exception_on_error_code( my_error_code const & e ) { if( e.exc_ ) std::rethrow_exception( e.exc_ ); else throw std::system_error( e.code_ ); }