开发者

Setter in exception class

What could be the implications of having a setter member function in an exception class? The motivation for hav开发者_运维百科ing a setter is that sometimes there isn't enough data available at the point of throw in order to handle the exception properly at the point of catch; so the additional information has to be added when the stack is being unwound.


Check out the Boost.Exception library and most precisely this page in the paragraph titled Adding of Arbitrary Data to Active Exception Objects:

void parse_file( char const * file_name )
{
    boost::shared_ptr<FILE> f = file_open(file_name,"rb");
    assert(f);
    try
    {
        char buf[1024];
        file_read( f.get(), buf, sizeof(buf) );
    }
    catch(boost::exception & e )
    {
        e << boost::errinfo_file_name(file_name);
        throw;
    }
}

Personally I find the technic pretty effective. Modify the exception (adding context) and rethrow.

Contrary to Java, in C++ you decide whether or not you include the stack frame when building your exception, so you don't incur the risk of losing it and it'll still refer to the point of the code that threw the first exception, while having significant context.


While you could doctor the original exception, I would prefer the technique used in Java: you catch the original and throw a new exception that refers to the original as its cause.


First of all, this sounds like a good idea.

I use SEH (windows-specific exception handling, not related to C++) rather than C++ exception handling. Specifically because of this - it allows to collect much more information before the stack unwinding begins.

But I've never thought about throwing a type that will "collect" information.

Technically speaking - there's no problem. I know how exception handling is implemented by MSVC (up to assembler level), and there's nothing wrong with the idea. There some points that should be mentioned:

  1. The catch block is invoked after the stack has been unwound. So that everything within the appropriate try block has already been destroyed.
  2. Rethrowing an exception causes a significant performance hit.


I guess the underlying problem is that the throwing (low-level) code doesn't have as much context/information as code further up would have.

You can either create a new exception that describes the exception better, wrapping the original exception as an inner exception. I've done this a few times but I realize this is hardly practical in all circumstances.

I know some frameworks have a "Data"-property which is more or less a dictionary with arbitrary data. It doesn't sound bad to me, although it opens up for abuse. It probably shouldn't be used to make programmatic decisions, it should be for human consumption.

If something catches the exception, and makes decisions based on parameter X it could become quite messy.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜