Exception Handling – How to Manage Fired Listeners Exceptions

design-patternsexceptions

This is more of a design question and i was hoping to get pros and opinions on what makes sense.

BACKGROUND

Imagine something that holds one or more event listeners. Every now and then the thing fires events to its listeners.

PROBLEM

The problem is of course that listeners that follow after a listener that throws never get to know about the event. THis means that the order of listeners thus is an issue.

SOLUTION #1

Execute all listeners catching any thrown exceptions. This means all listeners are fired but in itself introduce other problems.

What should be done with caught exceptions ?

  • One option is to catch them all and after firing all events throw another exception which holds all the problems. ++
  • The other option is to log ~~
  • The last is to simply ignore these exceptions. —
  • Listeners are executed in isolation which is good. ++

SOLUTION #2

This option is the simplist and simply lets any thrown exception from a listener escape, resulting in remaining listeners never getting fired. Problems with this approach mean that

  • the order of listeners is significant(-)
  • simple to implement(+).
  • before listeners can affect the caller

Q

Which approach makes sense and causes the least number of problems. Does it really make sense to isolate listeners so they get events but cannot cause a running operation to abort if they throw ?

Best Answer

A couple of points to consider:

Listeners should be well-behaved in as much that they protect their own code's execution from letting exceptions escape to the outside.

The event firer (?), that is the one firing the event, has (should have) no interest in whatever the listeners do with it. Its only job is to ensure that all listeners get to hear about the event. This means that it should protect against one of the listeners doing anything that would prevent other listeners from getting the event. So, yes, catch exceptions.

The event firer has no interest in catching exceptions other than to ensure that bad behaviour by one listener doesn't affect other listeners. So in this case "eating" the exception could be argued for. However, eating exceptions doesn't help anybody, so logging the exception with as much detail about the offending listener as possible is the way to go.

I wouldn't have the firer collect exceptions and finally raise one of its own accord. Quite simply because the firer did its job correctly and has no need to throw an exception. By logging the exceptions thrown by badly behaving listeners, the firer is already doing its part in aiding any debugging needed. (Logs should always be free of exceptions...).