[Journal - Do Not Throw Exceptions in Event Handlers]

Do Not Throw Exceptions in Event Handlers

Saturday, February 26, 2005

Exception handling works closely with the method stack. The decisions when to throw exceptions, and where to handle them, are a natural part of the method design process. The focal point is what the method does. Typically (of course, *not* typically, but I'm being cynical), a short glance at the method's name clears the point.

In short, a method should throw an exception if it cannot fulfill its contract, that is, when it fails to do what it has promised its callers to do. So the question is, "What is the task of this method?"

It's important to remember that a method is primarily responsible to its caller. So, a more useful question is, "What does the caller rightfully expect of this method?"

Let's answer this question with regard to event handlers (the methods in question) and its callers (event raising code in the sender object).

Where do events fit the greater picture? Events are one of several forms to implement callbacks. Other forms are plain function pointers or delegates, interfaces, or derived classes overriding methods. In all cases, someone mixes in custom code called by someone who doesn't need to know about it. The differences between the various forms can be distinguished by looking at the caller-callee relation: Overridden method are optional replacements of code; interfaces are required provisions of code, defined by a strict contract, often implementing what is known as a "strategy"; plain delegate callbacks are similiar, but simpler than interfaces. Events are anonymous, optional notifications for the benefit of interested parties, namely, the event listeners.

Therefore, the event sender does not expect anything of its listeners, and event handlers therefore have no obligation to the event raising code in the sender. They only trigger actions in the appliction, and when something fails, they're not liable.

Update (Saturday, October 22, 2005): I'd like to clarify what follows from that statement and the premises set above: "not liable" does not mean "what the heck, let her crash", but in the presence of failure, "having no obligation to signal failure to the caller". The event handler should not throw, rethrow, or even pass on (let go unhandled) any exception.

All you have to do in an event handler is to report the exception, but see the next installment for tips on how to do it.