Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do exceptions propogate out of an event handler?

Consider the following program. How is the behaviour that it displays (namely that exceptions will propagate out of an event handler) a "good thing"? As far as I can tell, it could only ever be bad; unexpected exceptions popping up from functions that they shouldn't. In my particular case, it was killing threads. So, is this behaviour actually a good thing in some cases? Is this a reason to say that letting exceptions out of event-handlers is poor design?

static class Program {
    static void Main()
    {
        Foo foo = new Foo();
        foo.SomeEvent += ThrowException;

        try 
        {
            foo.OnSomeEvent();
        } 
        catch (Exception) 
        {
            // This is printed out
            Console.WriteLine("Exception caught!");
        }
    }

    static void ThrowException(object sender, EventArgs e)
    {
        throw new Exception();
    }
}

// Define other methods and classes here
class Foo 
{
    public event EventHandler SomeEvent;

    public void OnSomeEvent()
    {
        SomeEvent(this, EventArgs.Empty);
    }
}
like image 491
Matthew Scharley Avatar asked Nov 29 '22 20:11

Matthew Scharley


1 Answers

What's your preferred alternative - silently swallowing the exception? I wouldn't like that at all.

Events are just a way of implementing the observer pattern, really. If a listener throws an exception, I'd absolutely expect that exception to be thrown back to the caller. Any other behaviour I can think of would effectively treat the exception as unimportant. The whole point of exceptions is that when something goes wrong, you find out about it quickly and implicitly. You have to explicitly handle exceptions, so that you don't go on your merry way in a corrupt state without realising it.

You make a valid point about whose responsibility it is to handle exceptions. Broadly speaking, I find it best to assume that just about anything can throw an exception at any time. Other than special cases where I know a specific exception may occur and I can handle it, I don't usually catch exceptions other than at the top level - except possibly to wrap and rethrow, or log and rethrow.

Now it's possible that one of your event handlers really shouldn't be throwing an exception - that they haven't really run into an error condition - but what should happen if it's a perfectly reasonable exception which indicates a serious problem? While a program crashing is ugly, it's often better than continuing with some of it malfunctioning, possibly corrupting persisted state etc.

Fundamentally, I don't think the CS/SE field has got error handling "right" yet. I'm not even sure that there is an elegant way of doing the right thing which is simple to express in all situations... but I hope that the current situation isn't as good as it gets.

like image 52
Jon Skeet Avatar answered Dec 04 '22 12:12

Jon Skeet