Known wiki pages dealing with exceptions or error handling in general include:
Defining Exception Types:
Raising Exceptions:
Is anyone aware of any published patterns for using exceptions? Or are there any here on the wiki? I've been doing things with exceptions for years but the things I do don't make me feel like I've mastered them. I'm familiar with the C++ stdlib usage and Stroustrup's suggestions in his 3rd edition book, and I've seen quite a few other folk muddle with the things in java, perl and tcl, but I really feel there ought to be something more comprehensive to using them. I'm almost tempted to see them as another dimension to a class diagram, and I think they ought to relate directly to UnitTests - but don't know how to realize that. Surely there are better ideas. ExceptionPatternLanguage? anyone? -- PeterMerel
Actually, look at the page for JavaIdioms where there are a few idioms about using exceptions that might constitute a pattern language. It also ties into a few other interesting wiki threads you might benefit from reading.
-- KyleBrown
I'll go out on a limb and suggest a pattern. I call it AvoidExceptionsWheneverPossible.
Gee, that almost makes a complete language!
-- BillTrost (feeling a bit extreme...)
Exceptions arguably relate to PreConditions?. Either the routine succeeds, in which case it returns normally, or else it fails, in which case it throws an exception. It doesn't half-succeed. {WishfulThinking?} So conceptually, the exception is thrown before the routine has done any work, as part of a method preamble. So the code which is deciding whether to throw the exception is effectively testing a kind of PreCondition.
However, this kind of PreCondition doesn't signify a bug. Why not? Because there are conditions that the calling routine cannot reasonably ensure. If it wasn't for these, we could make the calling routine responsible for the tests and exceptions would never be thrown in a bug-free program.
Examples:
We can also throw exceptions when the caller is responsible for ensuring the PreCondition. These cases are always bugs. However, I don't think these bugs overlap with the kinds of bugs tested by UnitTests. A PreCondition on a routine is not there to check the routine, it's there to check all the other routines which call it; a UnitTest only tests its unit. It seems to me that UnitTests have nothing to say about verifying PreConditions?.
-- DaveHarris
Either the routine succeeds, in which case it returns normally, or else it fails, in which case it throws an exception.
This relates to the main problem I have with exceptions. Whenever a method which actually does something fails and throws an exception, it will often have done a little bit of whatever it was meant to be doing. Verifying preconditions is fine, but exceptions can't be used as a general way of implementing a rollback without carefully adding clean-up code in the catch block, or before the exception is thrown.
This may seem obvious, but a lot of the books that I have read place emphasis on localizing your error-handling code. However, I would argue that if you throw exceptions from an arbitrary place in a while loop, for example, you have no idea in the related catch block (or calling method) how much of the loop has been executed.
Should we TidyUpBeforeThrowing?
-- DavidMcNicol
Sounds like a good pattern-yet-to-be-born. Might I add another JavaIdiom related to it, which is UseFinallyClause. -- KyleBrown
Aren't TidyUpBeforeThrowing and ObserveSimpleThings? special cases of ChangeComplexObservablesUsingTransactions?? The point is to make the state changes atomic; all of nothing; never visible as half-completed. -- DaveHarris
Yes and no. They all embody the same general principle, which is that an Observable should always let all its observers know about any changes. The difference is in the complexity of the Observable. The question is: how do you achieve that in code. The first two are about the Observable itself. and the ideas are:
In the JavaBeans framework, this doesn't seem to be accounted for at all (for example, if number 15 says "no," I don't have an obligation to go back and tell the first 14 observers "never mind").
And it seems kinda hard to deal with it. But, once again, we're probably outside the bounds of common practice.
According to the JavaBeans spec, if a vetoable event is refused by one of the event listeners, the bean should then fire the event again with the current value to inform all listeners that the value has been rolled back. However, it does not say what happens if one of the listeners vetoes the rolled back value! -- NatPryce
I would have said that's not the beans problem. If the listener accepted the value once (which it must have done if the property was in that state originally), vetos a first change from x to y, and then vetos the second change (from x to x) It's a flaw in the listener. No ?
-- AlanFrancis
A listener could see, and agree to, the first change from x to y. If a later listener then vetoed the change, the first listener would next see a change from y to x, but would not be able to tell that the change was because of a veto.
For example, the first listener might only allow a property to have monotonically increasing values. If y > x, the it would allow the first change but would veto the roll-back.
-- NatPryce