Throwing a new exception while throwing an old exception

久未见 提交于 2019-12-05 11:13:27

Think in terms of flow control. Exceptions are fundamentally just fancy setjmp/longjmp or setcc/callcc anyway. The exception object is used to select a particular place to jump to, like an address. The exception handler simply recurses on the current exception, longjmping until it is handled.

Handling two exceptions at a time is simply a matter of bundling them together into one, such that the result produces coherent flow control. I can think of two alternatives:

  • Combine them into an uncatchable exception. It would amount to unwinding the entire stack and ignoring all handlers. This creates the risk of an exception cascade causing totally random behavior.
  • Somehow construct their Cartesian product. Yeah, right.

The C++ methodology serves the interest of predictability well.

Lucass

You can chain exceptions. http://java.sun.com/docs/books/tutorial/essential/exceptions/chained.html

try {

} catch (IOException e) {
    throw new SampleException("Other IOException", e);
}

You can also have a try catch inside your finnally too.

try{
}catch(Exception e){
}finally{
    try{
      throw new SampleException("foo");
    }catch(Exception e){
    }
}

Edit:

Also you can have multiple catches. I don't think multiple exceptions would be a good idea, because an exception is already something you need to recover from. The only reason to have more than one exception I can think of is if you use it as part of your logic (like multiple returns), wich would be deviating from the original purpose of the idea of the Exception. Besides, how can you produce two exceptions at the same time?

Could a programming language handle multiple exceptions? Sure, I don't see why not. Would this be useful? No, I would say it would not be. Error handling and resumption is very hard as it is - I don't see how adding combinatorial explosion to the problem would help things.

Yes, it is possible for a language to support throwing multiple exceptions at a time; however, that also means that programmers need to handle multiple exceptions at a time as well, so there is definitely a tradeoff. I have heard of languages that have this although I am having trouble coming up with the list off the top of my head; I believe LINQ or PLINQ may be one of those languages, but I don't quite remember. Anyway, there are different ways that multiple exceptions can be thrown... one way is to use exception chaining, either by forcing one exception to become the "cause" or "previouslyProgatingException" of the other, or to bottle all of the exceptions up into a single exception representing the fact that multiple exceptions have been thrown. I suppose a language could also introduce a catch clause that lets you specify multiple exception types at once, although that would be a poor design choice, IMHO, as the number of handlers is large enough as is, and that would result in an explosion of catch clauses just to handle every single possible combination.

C++ std::exception_ptr allows you store exceptions. So it should be possible to embed exceptions in other exceptions and give you the impression that you have the stack on thrown exceptions. This could be useful if you want to know the root cause of the actual exception.

One situation where multiple thrown exceptions in parallel might be useful, is unit testing with JUnit:

  • If a test fails, an exception is thrown (either produced by code under test or an assertion).
  • Each @After method is invoked after the test, whether the test fails or succeeds.
  • If an After method fails, another exception is thrown.
  • Only the exception thrown in the After method is displayed in my IDE (Eclipse) for the test result.

I know that JUnit notifies its test listeners about both exceptions, and when debugging a test in Eclipse I can see the first exception appearing in the JUnit view, only to be replaced by the second exception shortly after.

This problem should probably be resolved by making Eclipse remember all notifications for a given test, not only the last one. Having "parallel exceptions", where the exception from the finally does not swallow the one from the try, would solve this issue too.

If you think about it, the situation you've described has Exception("First") as the root cause of Exception("second"), conceptually. The most useful thing for the user would probably be to get a stack dump showing a chain in that order...

In managed platforms, I can think of situations where it might be useful to have a disposer "elevate" an exception to something which is stronger, but not totally fatal to an application. For example, a "command" object's disposer might attempt to unwind the state of its associated connection to cancel any partially-performed commands. If that works, the underlying code may attempt to do other things with the connection. If the attempted "cancel" doesn't work, the exception should probably propagate out to the level where the connection would have been destroyed. In such a case, it may be useful for the exception to contain an "inner exception", though the only way I know to achieve that would be to have the attempted unwinding in a catch block rather than a "finally" block.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!