Known wiki pages dealing with exceptions or error handling in general include: '''Defining Exception Types:''' * NameTheProblemNotTheThrower * ExceptionPerContext * RefineExceptions * HomogenizeExceptions * GeneralizeOnExceptionBehavior '''Raising Exceptions:''' * DesigningWithExceptions * TidyUpBeforeThrowing * SecurityDoorPattern * BouncerPattern * ExceptionsTidyThreads * ExceptionsCancelTransactions * ExceptionReporter * ExceptionLogging * DontThrowGenericExceptions '''Handling Exceptions:''' * LetExceptionsPropagate * ThrowDontCatch * CatchWhatYouCanHandle * DontCatchRuntimeExceptions * ConvertExceptions * NestedException * NullCatchClause / EmptyCatchClause * UnhandledException * AbortRetryIgnore (Exceptions with ContinuationPassingStyle) '''Exceptions and testing''' * ThrowYourOwnException * DesignByContract '''When to use exceptions:''' * UseExceptionsInsteadOfErrorValues * DontUseExceptionsForFlowControl * AvoidExceptionsWheneverPossible * CodeWithoutExceptions '''Alternatives to Using Exceptions''' * NullObject''''''s * ErrorValue''''''s * PassAnErrorHandler * InvisibleExceptionHandlers (more or less an AntiPattern) * SoftwareTransactionalMemory * UseAssertions * WhatAreAssertions * DoNotUseAssertions * AssertionsAsComments * CountInAssertions * ExceptionalValue * BottomPropagation * ReplaceEmptyCatchWithTest * LookBeforeYouLeap * But CoupleLeapingWithLooking '''CeePlusPlusIdioms:''' * ResourceAcquisitionIsInitialization * BewareOfExceptionsInTheDestructor * DontDeclareThrownExceptions * Make and honor ExceptionGuarantee''''''s '''CeeIdioms:''' * ErrorCode * ErrorCodeAndErrno * ZeroIsSuccess * NonNegativeIsSuccess * NegativeIsFailure '''JavaIdioms:''' * EfficientContractsInJava * UseFinallyClause * ExceptionTunneling * CheckedExceptionsAreOfDubiousValue * JavaExceptionsAreParticularlyEvil * DeclareThrowsExceptionByDefault '''Discussion:''' * ExceptionHandlingChallenge * IterativeGrowthRequiresExceptions * ClassifyingExceptions * ExceptionsAreOurFriends * ExceptionsMaskRealProblems * ObserversAndExceptions * ObserversShouldNeverThrowExceptions * ObservablesNeedToBeConsistent * ChangeComplexObservablesUsingTransactions * ObserveSimpleThings * YouDontWantAnExceptionYouWantaTimeMachine * YouDontWantAnExceptionYouWantaTransaction * IlluminateTheMainline * ExceptionHandlingNearMainline * ExceptionsAsConstraints '''Related Web Resources''' * More Effective C++ isbn:020163371X * There is a collection of patterns on error handling at http://www.objectarchitects.de/arcus/cookbook/exhandling/index.htm. ---- 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 UnitTest''''''s - 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: * The PreCondition for Matrix.invert() might be Matrix.nonSingular(), but the test for singularity does most of the work of inversion so you might as well combine them. * Syntax errors in an input stream. The parser can throw an exception if it sees a syntax error; it is not reasonable for the caller to only pass error-free streams because the effort of checking for errors is equivalent to parsing. * There may be cases (like detecting end-of-file during a block copy) where the calling routine '''could''' economically detect the error, but it is a more convenient division of labour to have the callee do it. To do otherwise would mean replicating the test code at every point-of-call. ''"I think they ought to relate directly to UnitTest''''''s."'' - As I understand it, UnitTest''''''s check for bugs. So they are orthogonal to the non-bug-related exceptions I've just discussed. (Of course, we can use UnitTest''''''s to check that exceptions are thrown when expected.) 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 UnitTest''''''s. 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 UnitTest''''''s 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: * Either make the Observable simple enough that exceptions don't occur when you send it a message (for example, make it a ValueObject) * Or write the Observable so that it cleans up after itself when exceptions arise. Transactions can arise on the Observable side of the house when: * A whole sequence of changes to the Observer need to go as an all or one. In which case you need to do a two-phase commit where the commit triggers the notifications (examples, anyone ?). Or they can arise on the Observer side of the house when: * The observers can veto a change (as per the JavaBeans vetoable properties model) and the observable needs to manage a two phase commit with its observer * The observers can throw exceptions (essentially a more virulent form of the above). One thing that worries me about the JavaBeans stuff: it seems awful hard to make it re-entrant/thread safe. I mean, suppose I'm an observable with 17 observers and I iterate through them, asking each one "Are you in a state such that you can accept this change." Until I iterate through again saying "okay I've changed," they're obliged to remain in such a state. In some sense, I've locked them in. 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. -- WilliamGrosso 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 ---- CategoryException CategoryRoadmap