
Emil Dotchevski wrote:
<snip> I see. This feature is most valuable. However, so is Tom's suggestion and I don't think both are mutually exclusive (that is if we let go of using the template-id 'error_info' for the latter):
typedef boost::custom_exception<tag:: errno,tag::filename,tag::size> file_error;
Consider this code:
void read_file( char const * filename ) { something_unrelated(); .... if( file_failure ) throw file_error() << error_info<tag_filename>(filename); }
If I understand correctly, you are concerned with making sure all file_error exceptions pack a file_name.
No, not my point. It's about increasing the expressiveness of client code: It provides means for a user to express: "I'm going to throw a bunch of exceptions (starting) with common attributes. Please give me a brief way to create them, so error reporting doesn't obscure my code." It also allows to easily port "traditional" exception classes to boost::exception. Further it would allow to allocate the attributes of a custom_exception in one shot.
But what if "something_unrelated" throws? Isn't the filename known to our function relevant to that other failure too?
Since it was an abstract example it sure depends on the case.
It sure is, despite that we have no idea what exceptions "something_unrelated" could throw.
So, I'd write that function like this:
void read_file( char const * filename ) { try { something_unrelated(); .... if( file_failure ) throw file_error(); } catch( boost::exception & x ) { x << error_info<tag_filename>(filename); throw; } }
How would your custom_exception idea fit in this framework?
So now you're bringing up a different use case. Of course you're still free to use this pattern at any factorization that is reasonable e.g. providing a 'file_error' base class and an 'io_error' custom_exception that always adds 'errno' and an enum describing the failed operation. Regards, Tobias Schwinger - Review Manager -