
On 9/30/07, Tom Brinkman <reportbase@gmail.com> wrote:
3) Support for linking multiple error tags in a single expression might be useful and help in standarizing errors throughout an application.
throw boost:::exception() << boost::error_info<tag_errorno,tag_filename,tag_size,tag_width>( (1,"output.txt",100,200);
Could you clarify what you mean?
Well, I could do something like this:
typedef boost::error_info<tag_errorno, tag_filename,tag_size,tag_width> error_t;
throw error_t(1,"output.txt",100,200);
You probably mean: throw my_error() << error_t(1,"output.txt",100,200); In my opinion what you're describing is better accomplished like this: class my_error: public boost::exception { public: my_error( int errno, std::string file_name, size_t size, int width ) { (*this) << boost::error_info<tag_errno>(errno) << boost::error_info<tag_file_name>(file_name) << boost::error_info<tag_size>(size) << boost::error_info<tag_width>(width); } }; However in my experience with Boost Exception I've never done that. Occasionally I've defined a local function that's called within a given compilation unit, like this: namespace { void throw_my_error( int errno, std::string file_name, size_t size, int width ) { throw my_error() << boost::error_info<tag_errno>(errno) << boost::error_info<tag_file_name>(file_name) << boost::error_info<tag_size>(size) << boost::error_info<tag_width>(width); } } I think it is a mistake to standardize globally on the info you want to stuff into the exception at the time of the throw. What if you detect an error condition that matches the my_error semantics completely, yet you don't have a file name to pass to its constructor? You'd find a way to make the file name available to the throw site, right? Instead, Boost Exception allows you to just throw my_error(), even though you don't have all info needed to handle it; such info can be added later on, as the exception bubbles up to a context where it is available naturally. Similarly, what if you are throwing my_error, but you have additional info that is relevant to the failure? Sure, you could modify the my_error definition to add another constructor, but that's an overkill -- not to mention undesirable because it may force a lot of files to recompile. When I use Boost Exception, the two things I care about are: * Define clear semantics for each exception type * Correctly classify the failure (derive the appropriate bases.) Other than that, all of my exception classes look very much the same: they're empty. This could go into a "best practices" section in the documentation, if we agree that this really is the best approach. Emil Dotchevski