10 Aug
2009
10 Aug
'09
9:58 p.m.
Emil Dotchevski wrote: >>> catch( foo & e ) >>> { >>> //do other stuff, and then: >>> std::cerr << boost::diagnostic_information(e); >>> } >>> catch( boost::exception & e ) >>> { >>> //do other stuff, then: >>> std::cerr << boost::diagnostic_information(e); >>> } >> 1. Isn't supposed to be other way around: first catch boost::exception, >> followed >> by catch foo? I'd prefer to have boost:exception related logic in a single >> catch >> clause instead of being spread between 20. > > 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. >> 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. > 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. > Later on, when you catch(another_exception &), you can pass the stored > exception_ptr to boost::diagnostic_information, and you'll get > diagnostic information about the exception it holds (the one captured > by boost::current_exception() in the original catch(...)). Or you can > rethrow it and use suitable catches to handle it. That's fine. As I said I want only inception point and "cause" string and I want to format final message myself. >>> 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? >>>> 3. I pretty much only need file, line and function name. Are you >>>> saying I can't do what you are doing inside diagnostic information >>>> to get a hold of them? >>> If the exception was thrown by BOOST_THROW_EXCEPTION, then yes you'd >>> have file, line and function name. >> 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? >>> However, objects that derive from >>> boost::exception can have data of arbitrary type, some of it added at >>> the point of the throw, some of it added later (meaning, it depends on >>> the callers of the function that throws.) >>> >>> Do you not want to display all that information when you catch a user >>> exception in the testing framework? >> I do not mind if method 'what' would generate "rich" error message including >> everything, but the information about the point of inception (Or some other >> method) > > The problem with what() is that some programmers use it to return a > user-friendly message. This is incorrect because in general > user-friendly messages have to be localized which clearly goes beyond > what()'s interface. Can we have something like 'cause', which will be the same as diagnostic_info, but without inception point? Gennadiy