
Michael, You're right, the boost::current_exception function is only valid within a try block. The issue you're raising has to do with the postconditions of operator<<. Its current semantics guarantee that upon return the error info is successfully stored in the exception object. This means that when you catch an exception, you can rely on certain error info to be present: catch( file_read_error & e ) { assert(get_error_info<errinfo_file_name>(e)!=0); std::cerr << "Error reading " << *get_error_info<errinfo_file_name>(e); } Without this guarantee, the catch site would be required to deal with any exception even if it has no error info in it. If you are to add error info to exception objects in destructors, this guarantee can not hold. So it seems that even though it is less convenient and more explicit, the catch( boost::exception & e ) { e << errinfo_file_name(n); throw; } approach is preferable. That said, I am not against implementing a generic type that adds error info in its destructor as you and others have suggested, as long as it is kept separate and doesn't change the current op<< postconditions. Implementing this functionality in a portable manner is not trivial, but if you or someone else wants to tackle it, I can provide some support. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode On Tue, Jun 14, 2011 at 2:45 PM, Michael Schuerig <michael.lists@schuerig.de> wrote:
The FAQ for boost exception contain this example snippet for adding further information to an exception while the call stack is unwound
catch( boost::exception & e ) { e << foo_info(foo); throw; //Okay, re-throwing the original exception object. }
I like that this possible, but I think the resulting code is somewhat tedious:
void foo(const string& file_name) { try { do_something_fallible(file_name); } catch( boost::exception & e ) { e << boost::errinfo_file_name(file_name); throw; } }
I'd rather write it like this:
void foo(const string& file_name) { diagnostic<errinfo_file_name>(file_name); do_something_fallible(file_name); }
My first, non-generic attempt fails:
class diagnostic { public: explicit diagnostic(const string& file_name) : file_name_(file_name) {} ~diagnostic() { if ( boost::exception_ptr e = boost::current_exception() ) { *e << boost::errinfo_file_name(file_name_.c_str()); } } private: const string file_name_; };
The requirements for boost::current_exception() state that it may only be called inside a catch block, therefore the code above is illegal to begin with. Ignoring that, operator<< doesn't appear to be suitably overloaded for this use, anyway.
Now, I'm wondering, is what I'm trying to achieve a bad idea? If not, is there another way to do it?
Michael
-- Michael Schuerig mailto:michael@schuerig.de http://www.schuerig.de/michael/ _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users