exception error_info list?

Hi, what do you think about exposing the error_info-map of boost::exception? I would like to get all attached error infos from one exception. Then, everyone could implement his own version of diagnostic_information() without relying on boost internals. Beside that, I had another idea: When translating an exception it would be possible to copy all error_infos from the originating exception to the new one. How do you handle this loss of information at the time? thanks.

On Fri, Oct 9, 2009 at 5:48 PM, denis <mu_kuh@yahoo.de> wrote:
what do you think about exposing the error_info-map of boost::exception?
I would like to get all attached error infos from one exception.
I've never been able to do anything generic with the error_infos, other than dumping (user-unfriendly) diagnostic information, which is what boost::diagnostic_information is for.
Then, everyone could implement his own version of diagnostic_information() without relying on boost internals.
You do have some control over the output of diagnostic_information: you can provide to_string overloads which Boost Exception will bind through ADL at the time the error_info template is instantiated (see http://www.boost.org/doc/libs/release/libs/exception/doc/diagnostic_informat....) You can either overload to_string for boost::error_info<Tag,T> or just for T; the former lets you convert the same T differently depending on Tag, while the latter lets you convert any T regardless of Tag. For an example, see how errinfo_errno implements to_string in terms of strerror in http://svn.boost.org/svn/boost/trunk/boost/exception/errinfo_errno.hpp.
Beside that, I had another idea: When translating an exception it would be possible to copy all error_infos from the originating exception to the new one. How do you handle this loss of information at the time?
A copy of a boost::exception shares error_info ownership with the original. Does this work for your use case? Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
On Fri, Oct 9, 2009 at 5:48 PM, denis <mu_kuh@yahoo.de> wrote:
what do you think about exposing the error_info-map of boost::exception?
I would like to get all attached error infos from one exception.
I've never been able to do anything generic with the error_infos, other than dumping (user-unfriendly) diagnostic information, which is what boost::diagnostic_information is for.
I have an exception base-class which provides a virtual function user_message() where derived classes can generate a user-friendly message from their error_infos. See the example at the end.
Then, everyone could implement his own version of diagnostic_information() without relying on boost internals.
You do have some control over the output of diagnostic_information: [...]
Yes, but even if the output is not for end-users, I would like to keep the log-file as readable as possible for the support team. And not at least for me. For example I don't need the line "Throw in function (unknown)" (I rarely use BOOST_THROW_EXCEPTION) And I could use abi::__cxa_demangle to print a more readable name of an exception or error_info.
Beside that, I had another idea: When translating an exception it would be possible to copy all error_infos from the originating exception to the new one. How do you handle this loss of information at the time?
A copy of a boost::exception shares error_info ownership with the original. Does this work for your use case?
I don't think so. Where could I copy the exception in the following example, so that my_error() would have the error_infos from e? struct my_error : public ex::exception { virtual std::string user_message () const { // format() is just a little helper function in the base // class using boost::get_error_info and boost::format return format<boost::errinfo_file_name, boost::errinfo_errno> ("The file %1% could not be read because %2%"); } }; // -- snip -- try { mylib::func(); // func throws with attached boost::errinfo_errno } catch (mylib::system_error& e) { throw my_error() << e?? << boost::errinfo_file_name ("foo"); } regards, Denis

On Sat, Oct 10, 2009 at 6:06 AM, denis <mu_kuh@yahoo.de> wrote:
Emil Dotchevski wrote:
On Fri, Oct 9, 2009 at 5:48 PM, denis <mu_kuh@yahoo.de> wrote:
I would like to get all attached error infos from one exception. <snip> Then, everyone could implement his own version of diagnostic_information() without relying on boost internals.
You do have some control over the output of diagnostic_information: [...]
Yes, but even if the output is not for end-users
You are right, this output is not for end users.
For example I don't need the line "Throw in function (unknown)" (I rarely use BOOST_THROW_EXCEPTION) And I could use abi::__cxa_demangle to print a more readable name of an exception or error_info.
This is a good point, the "function (unknown)" should not be printed if the function is unknown. Also, demangling the identifiers is on my todo list. Please don't get me wrong, I'm all for improving the output of diagnostic_information. I'll accept any patches towards that goal.
Beside that, I had another idea: When translating an exception it would be possible to copy all error_infos from the originating exception to the new one. How do you handle this loss of information at the time?
A copy of a boost::exception shares error_info ownership with the original. Does this work for your use case?
I don't think so. Where could I copy the exception in the following example, so that my_error() would have the error_infos from e?
struct my_error : public ex::exception { virtual std::string user_message () const { // format() is just a little helper function in the base // class using boost::get_error_info and boost::format return format<boost::errinfo_file_name, boost::errinfo_errno> ("The file %1% could not be read because %2%"); } };
// -- snip --
try { mylib::func(); // func throws with attached boost::errinfo_errno } catch (mylib::system_error& e) { throw my_error() << e?? << boost::errinfo_file_name ("foo"); }
I don't know what ex::exception is but here's some code that copies the error_infos from one exception to another: struct exception_base: virtual boost::exception, virtual std::exception { }; struct exception1: exception_base { }; struct exception2: exception_base { exception2(boost::exception const & e): boost::exception(e) { } }; try { .... } catch( exception1 & e ) { throw exception2(e); } Alternatively, you could use exception_ptr to store store the whole "low level" exception (error_infos and all) as an error_info: struct exception_base: virtual boost::exception, virtual std::exception { }; struct lib_exception: exception_base { }; struct app_exception: exception_base { }; typedef boost::error_info<struct nested_exception_,boost::exception_ptr> nested_exception; try { .... } catch( lib_exception & e ) { throw app_exception() << nested_exception(boost::current_exception()); } (By the way, diagnostic_information will recurse into nested exceptions and print the nested error_infos as well.) Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
Please don't get me wrong, I'm all for improving the output of diagnostic_information. I'll accept any patches towards that goal.
Did you had time to look at the identification lib from the vault ? I think it may helps this. -- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

Emil Dotchevski wrote:
Alternatively, you could use exception_ptr to store store the whole "low level" exception (error_infos and all) as an error_info:
struct exception_base: virtual boost::exception, virtual std::exception { }; struct lib_exception: exception_base { }; struct app_exception: exception_base { }; typedef boost::error_info<struct nested_exception_,boost::exception_ptr> nested_exception;
try { .... } catch( lib_exception & e ) { throw app_exception() << nested_exception(boost::current_exception()); }
(By the way, diagnostic_information will recurse into nested exceptions and print the nested error_infos as well.)
thank you for all the hints. Storing the original exception was my biggest concern. This feature of nested exceptions is very cool. It gets a little bit lost in the documentation. I'd vote for providing that typedef as a standard "boost::errinfo_...". I attached a small change for diagnostic_information. Unfortunately, I noticed that __cxa_demangle segfaults in certain circumstances (at least on debian and ubuntu). Please forget that function. regards, Denis ------------------------------------------------------------ --- diagnostic_information.hpp.org 2009-05-17 08:12:29.000000000 +0200 +++ diagnostic_information.hpp 2009-10-12 22:04:06.000000000 +0200 @@ -79,14 +79,11 @@ { tmp << *f; if( int const * l=get_error_info<throw_line>(*be) ) - tmp << '(' << *l << "): "; + tmp << '(' << *l << ')'; + tmp << ": "; } - tmp << "Throw in function "; if( char const * const * fn=get_error_info<throw_function>(*be) ) - tmp << *fn; - else - tmp << "(unknown)"; - tmp << '\n'; + tmp << "Throw in function " << *fn << '\n'; } #ifndef BOOST_NO_RTTI tmp << std::string("Dynamic exception type: ") <<

On Mon, Oct 12, 2009 at 1:43 PM, denis <mu_kuh@yahoo.de> wrote:
Emil Dotchevski wrote:
Alternatively, you could use exception_ptr to store store the whole "low level" exception (error_infos and all) as an error_info:
This feature of nested exceptions is very cool. It gets a little bit lost in the documentation. I'd vote for providing that typedef as a standard "boost::errinfo_...".
It isn't lost, just not advertised. :) The main motivation for exception_ptr is to support transporting of exceptions between threads. OTOH, I know that translating and nesting exceptions is popular, so adding a boost::errinfo_nested_exception typedef is probably a good idea. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode
participants (3)
-
denis
-
Emil Dotchevski
-
joel