On Mon, Aug 10, 2009 at 2:58 PM, Gennadiy Rozental
Emil Dotchevski wrote:
I was implying that you normally catch more specific exceptions first. If you don't care about foo in particular you can use a generic catch like catch(boost::exception/std::exception) or catch(...).
I do. I hoped I can handle throw foo() in catch( foo ) and BOOST_THROW_EXCEPTION( foo() ) in catch( boost::exception ). Former would not try to dig inception point info. Later would.
Actually I might want to do it in all clauses after all. I do want to be as specific as possible. An alternative is to somehow deduce type at runtime in generic catch boost::exception clause, but this seems non reliable.
I might not be understanding exactly what you're doing. In my mind, a testing framework should assume that (unless you're testing exception handling) any exception a test emits is unexpected, and then the only useful thing you can do is log some diagnostic information; I don't see a need for anything more than catch(...) { std::cerr << boost::current_exception_diagnostic_information(); } Here is an example of what this could display: example_io.cpp(83): Throw in function class boost::shared_ptr<struct _iobuf> __cdecl my_fopen(const char *,const char *) Dynamic exception type: class boost::exception_detail::clone_impl<class fopen_error> std::exception::what: example_io error [struct errno_ *] = 2, OS says "No such file or directory" [struct file_name_ *] = tmp1.txt [struct function_ *] = fopen [struct open_mode_ *] = rb By the way in some IDEs double-clicking the first line in the above message will open the source location in the editor.
2. I do not want to print anything. I collect information and return it (by throwing another exception) to the higher level, which in turn decides how and where to report it.
I don't see the point of throwing another exception
I need to report the error somehow, don't I? Including all the details.
Yes, and in my mind "all the details" are included in the string returned by boost::current_exception_diagnostic_information. If anything useful is missing from that string, then it should be included instead of doing something else.
but if that's what you want to do then you could use boost::exception_ptr:
catch(...) { BOOST_THROW_EXCEPTION(another_exception(boost::current_exception())); }
I do not see why I need BOOST_THROW_EXCEPTION. I do not care about this exception inception point. I know it ;) Also I throw this exception in all cases when an error occurred (for example in case if signal triggered). It operates on strings and numbers.
Sure, you can throw any exception without BOOST_THROW_EXCEPTION. However there's virtually no overhead in using BOOST_THROW_EXCEPTION. It does not allocate memory, yet allows users to add arbitrary data in the exception and to get a boost::exception_ptr to it.
catch( std::exception & e ) { //do other stuff furst, then: std::cerr << boost::diagnostic_information(e); } catch( ... ) { std::cerr << boost::current_exception_diagnostic_information(); }
What is the point of trying to dig something here? Wouldn't the boost::exception based exception will always be caught in 'catch boost::exception' clause above?
If all you do is get diagnostic_information, then just the catch(...) is sufficient.
But If I already have catch( boost::exception ) I should not try to dig this info in catch(...) right?
In this particular case, what would you do with a boost::exception that's different from what you'd do with any other exception in a catch(...)?
Ok. So how do I do this?
Use get_error_info
(e), get_error_info (e), get_error_info (e). What is the requirement on type of e? can it be char*? Or std::string?
e is the exception you catch. Here's how you use it:
if( char const * const * f=get_error_info
Can we have something like 'cause', which will be the same as diagnostic_info, but without inception point?
For what reason? It seems to me that you're trying to make the returned string "prettier" which is unrealistic. The string is pretty much guaranteed to be ugly to look at yet rather informative. :) That said, I do agree that especially if you're generating some kind of xml report, processing the location of the throw specifically is a good idea. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode