Rethrow recoil

The closure-based exception handling scheme in the previous blog post works almost perfectly, and it would have worked entirely perfectly if a catch block were an ordinary block of code. But alas, it is not. Not quite. A catch block is special in that there is one statement that you can make inside a catch block that you cannot make anywhere else in your program. Unfortunately, it is also a fairly common statement to use inside catch blocks: the rethrow statement – that is, a throw statement with no operand. We cannot simply use a throw statement with an operand instead, since that has different semantics. In fact, it’s not a rethrow at all, it’s a brand new throw (even when we’re using the exception we just caught). The consequence is that the original stack trace is lost. In other words, we lose trace of where the exception originally occurred, which is almost never what we want.

So that’s unfortunate. Unacceptable even. Can we fix it? Of course we can fix it! We’re programmers, we can fix anything!

There’s no way to put a rethrow into our lambda expession though, so we need to do something else. That something else turns out to be trivial. We do have a genuine catch-block available, so we’ll just put it there. Or rather, we’ll create a new try-catch block with a hard-coded rethrow inside, and put that block inside a new extension method which complements the one we created last time. Like so:


public static Func<TR> Touch<TR, TE>(this Func<TR> f, Action<TE> h)
where TE : Exception
{
return () =>
{
try
{
return f();
}
catch (TE e)
{
h(e);
throw;
}
};
}

view raw

Touch.cs

hosted with ❤ by GitHub

In this case, we use an Action<TE> instead of a Func<TE, TR>, because obviously the exception handler won’t be returning anything – we just hard-coded a rethrow in there!

Why Touch and not an overload of the Catch method we saw before? Well, first of all we’re not catching the exception, we’re merely touching it on the way through – hence Catch is not really a suitable name for what we’re doing. And besides, the following code snippet would be ambiguous, at least to the reader of the code. Assuming we had overloaded the Catch method, how should we interpret something like this?


Catch((Exception ex) => { throw ex; })

view raw

AmbCatch.cs

hosted with ❤ by GitHub

Is that an Action<TE> or a Func<TE, TR>? I have no idea. It turns out that the compiler is OK with the ambivalence – it decides it must be an Action<TE> (which leaves us with a rather strange catch block where the throw ex statement in the handler terminates the block before the rethrow occurs). But I’m not! Better to be explicit. Touch it is.

Now we can write code like this:


var g = f
.Catch((ArgumentException ex) => "Something")
.Touch((NullReferenceException ex) => Console.WriteLine("I saw you!"))
.Catch((Exception ex) => "ex");
Console.WriteLine(g());

So what happens in the last line? Well, if an ArgumentException is thrown, we’ll see the string “Something” written. If a NullReferenceException is thrown, however, we’ll see the “I saw you” string, in addition to “ex”, since the exception percolates up to the outer handler where it is caught and swallowed.

Fixed!


Linq to Exceptions

Lately I’ve been thinking about the mundane task of exception handling. Remarkably unsexy, and yet completely mandatory. There’s no escape from handling the exceptions that may (and therefore will) occur in your application, unless you want it to crash or misbehave regularly.

Proper exception handling can be a chore anywhere in your application, but in particular at integration points. Whenever your application needs to communicate with some external service, any number of things can go wrong, at various levels in the stack – from application level errors to network problems. We need to be able to cope with all these different kinds of errors, and hence we surround each service call with a veritable flood of exception handlers. That sort of works, but there are problems – first, the actual service is drowning amidst all the exception handling, and second, we get a lot of code duplication, since we tend to handle many kinds of exceptions in the same way for all service calls.

I’ve been discussing how to best solve this problem in a completely general and flexible way in several impromptu popsicle- and coffee-driven sessions with some of my compatriots at work (in particular Johan and Jonas – thanks guys!). Some of the code examples in this blog post, especially those who exhibit some trace of intelligence, can legitimately be considered rip-offs, evolutions, misunderstandings or various other degenerations of similar code snippets they have come up with.

But I’m getting ahead of myself. Let’s return to the root of the problem: how exception handling code has a tendency to overshadow the so-called business logic in our applications and to cause severe cases of duplication.

The problem is minor if there is a single exception we’re catching:


try {
// Interesting code.
}
catch (SomeException ex) {
// Dull exception handling code.
}

However, things regress quickly with additional types of exceptions:


try {
// Interesting code.
}
catch (SomeException ex) {
// Dull code.
}
catch (SomeOtherException ex) {
// Dull code.
}
catch (YetAnotherException ex) {
// Dull code.
}
catch (Exception ex) {
// Dull code.
}

This is a bit messy, and the signal-to-noise-ratio is low. It gets much worse when you have a second piece of interesting code that you need to guard with the same exception handling. Suddenly you have rampant code repetition on your hands.

A solution would be to use a closure to inject the interesting code into a generic exception handling method, like this:


TR Call<TR>(Func<TR> f) {
try {
return f();
}
catch (SomeException ex) {
// Dull code.
}
catch (SomeOtherException ex) {
// Dull code.
}
catch (YetAnotherException ex) {
// Dull code.
}
catch (Exception ex) {
// Dull code.
}
}

view raw

Coupled-Call.cs

hosted with ❤ by GitHub

And then you can use this in your methods:


Foo SafeMethod1(int x, string s) {
Call(() => Method1(x, s));
}
Bar SafeMethod2(double d) {
Call(() => Method2(d));
}

view raw

UsingCall.cs

hosted with ❤ by GitHub

Adding another method is trivial:


Quux SafeMethod3() {
Call(() => Method3());
}

This works pretty nicely and solves our immediate issue. But there are a couple of limitations. In particular, three problems spring to mind:

  1. What if you want to return some legal, non-default value of type TR from one or more of the catch-blocks? As it stands now, each catch-block must either rethrow or return the default value of TR.
  2. What if there are variations in how you want to handle some of the exceptions? For instance, it may be that YetAnotherException should be handled differently for each method.
  3. What if there are slight variations between the “catching” needs for the various methods? What if you decided that SafeMethod2 doesn’t need to handle SomeOtherException, whereas SafeMethod3 should handle IdiosyncraticException in addition to the “standard” ones?
  4. As an answer to the two first problems, you could pass in each exception handler to the Call method! Then you would have a method like this:


    TR Call<TR>(
    Func<TR> f,
    Func<SomeException, TR> h1,
    Func<SomeOtherException, TR> h2,
    Func<YetAnotherException, TR> h3,
    Func<Exception, TR> h4)
    {
    try {
    return f();
    }
    catch (SomeException ex) {
    return h1(ex);
    }
    catch (SomeOtherException ex) {
    return h2(ex);
    }
    catch (YetAnotherException ex) {
    return h3(ex);
    }
    catch (Exception ex) {
    return h4(ex);
    }
    }

    view raw

    CrazyCall.cs

    hosted with ❤ by GitHub

    And at this point you’re about to stop reading this blog post, because WTF. Now your methods look like this:


    Foo SafeMethod1(int x, string s) {
    Call(() => Method1(x, s),
    ex => // Handle SomeException,
    ex => // Handle SomeOtherException,
    ex => // Handle YetAnotherException,
    ex => // Handle Exception
    );
    }

    So we’re pretty much back at square one, except it’s a bit more convoluted and confusing for the casual reader. And we still don’t have a good solution for the third problem. We could of course fake “non-handling” of SomeOtherException for SafeMethod2 by simply handing in a non-handling handler, that is, one that simply rethrows directly: ex => { throw ex; }. But that’s ugly and what about the IdiosyncraticException? Well, it’s not going to be pretty:


    Quux SafeMethod3() {
    try {
    return Call(() => Method3(),
    ex => // Handle SomeException,
    ex => // Handle SomeOtherException,
    ex => // Handle YetAnotherException,
    ex => // Handle Exception
    );
    }
    catch (IdiosyncraticException ex) {
    // Do something.
    }
    }

    Which just might be the worst code ever, and also has the idiosyncracy that the additional catch-handler will only be reached if the Exception handler rethrows. Horrible. Better, perhaps, to put it inside?


    Quux SafeMethod3() {
    return Call(() =>
    {
    try { return Method3(); } catch (IdiosyncraticException ex) { throw ex; }
    },
    ex => // Handle SomeException,
    ex => // Handle SomeOtherException,
    ex => // Handle YetAnotherException,
    ex => // Handle Exception
    );
    }

    Well yes, slightly better, but still pretty horrible, and much worse than just suffering the duplication in the first place. But maybe we’ve learned something. What we need is composition – our current solution doesn’t compose at all. we need to be able to put together exactly the exception handlers we need for each method, while at the same time avoiding repetition. The problem is in some sense the coupling between the exception handlers. What if we tried a different approach, handling a single exception at a time?

    We could have a less ambitious Call-method, that would handle just a single type of exception for a method. Like this:


    TR Call<TR, TE>(
    Func<TR> f,
    Func<TE, TR> h)
    where TE : Exception
    {
    try {
    return f();
    }
    catch (TE ex) {
    return h(ex);
    }
    }

    view raw

    LessCall.cs

    hosted with ❤ by GitHub

    Now we have a single generic exception handler h. Note that when we constrain the type variable TE to be a subclass of Exception, we can use TE in the catch clause, to select precisely the exceptions we would like to catch. Then we could write a method like this:


    Frob SafeMethod4a() {
    return Call(
    () => new Frob(),
    (NullReferenceException ex) => … );
    }

    view raw

    SafeMethod4a.cs

    hosted with ❤ by GitHub

    What if we wanted to catch another exception as well? The solution is obvious:


    Frob SafeMethod4b() {
    return Call(
    () => SafeMethod4a(),
    (InvalidOperationException ex) => … );
    }

    view raw

    SafeMethod4b.cs

    hosted with ❤ by GitHub

    And yet another exception?


    Frob SafeMethod4c() {
    return Call(
    () => SafeMethod4b(),
    (FormatException ex) => … );
    }

    view raw

    SafeMethod4c.cs

    hosted with ❤ by GitHub

    You get the picture. Of course, we can collapse all three to a single method if we want to:


    Frob SafeMethod4() {
    return
    Call(() =>
    Call(() =>
    Call(() =>
    FrobFactory.Create(),
    (NullReferenceException ex) => … ),
    (InvalidOperationException ex) => … ),
    (FormatException ex) => … );
    }

    view raw

    SafeMethod4.cs

    hosted with ❤ by GitHub

    What have we gained? Well, not readability, I’ll admit that. But we’ve gained flexibility! Flexibility goes a long way! And we’ll work on the readability shortly. First, though: just in case it’s not clear, what we’ve done is that we’ve created an exception handling scenario that is similar to this:


    Frob TraditionalSafeMethod4() {
    try {
    try {
    try {
    return FrobFactory.Create();
    }
    catch (NullReferenceException ex) { … handler code … }
    }
    catch (InvalidOperationException ex) { … handler code … }
    }
    catch (FormatException ex) { … handler code … }
    }

    So there’s nothing very complicated going on here. In fact, I bet you can see how similar the two methods really are – the structure is identical! All we’ve done is replace the familiar try-catch construct with our own Call-construct.

    As an aside, we should note that the composed try-catch approach has slightly different semantics than the sequential, coupled try-catch approach. The difference in semantics is due to decoupling provided by the composed try-catch approach – each catch-block is completely independent. Therefore, there is nothing stopping us from having multiple catch-handlers for the same type of exception should we so desire.

    Now, to work on the readability a bit. What we really would like is some way to attach catch-handlers for various exception types to our function call. So assuming that we wrap up our original function call in a closure using a delegate of type Func<TR>, we would like to be able to attach a catch-handler for some exception type TE, and end up with a new closure that still has the type Func<TR>. Then we would have encapsulated the exception handling completely. Our unambitious Call-method from above is almost what we need, but not quite. Instead, let’s define an extension method on the type that we would like to extend! Func<TR>, that is:


    static class CatchExtensions
    {
    static Func<TR> Catch<TR, TE>(
    this Func<TR> f,
    Func<TE, TR> h)
    where TE : Exception
    {
    return () => {
    try {
    return f ();
    } catch (TE ex) {
    return h (ex);
    };
    };
    }
    }

    view raw

    Ext.Catch.cs

    hosted with ❤ by GitHub

    So the trick is to return a new closure that encapsulates calling the original closure and the exception handling. Then we can write code like this:


    Frob ExtSafeMethod4() {
    Func<Frob> it = () => FrobFactory.Create();
    var safe =
    it.Catch((NullReferenceException ex) => … )
    .Catch((InvalidOperationException ex) => … )
    .Catch((FormatException ex) => … );
    return safe();
    }

    Now the neat thing is that you can very easily separate out the catch-handler-attachment from the rest of the code:


    Frob ExtSafeMethod4b() {
    var safe = Protect(() => FrobFactory.Create);
    return safe();
    }
    Func<TR> Protect<TR>(Func<TR> it) {
    return
    it.Catch((NullReferenceException ex) => … )
    .Catch((InvalidOperationException ex) => … )
    .Catch((FormatException ex) => … );
    }

    So we have essentially created a fluent interface for attaching catch-handlers to a method call. The cool thing is that it is trivial to attach additional exception handlers as needed – and since we do so programmatically, we can even have logic to control the attachment of handlers. Say we discovered that we needed to catch WerewolfExceptions when the moon is full? No problem:


    Func<Frob> WolfProof() {
    var f = Protect(() => FrobFactory.Create());
    if (IsFullMoon()) {
    f = f.Catch((WerewolfException ex) => … ); // silver bullet?
    }
    return f;
    }

    view raw

    WolfProof.cs

    hosted with ❤ by GitHub

    In my eyes, this is pretty cool. You might be running away screaming, thinking I’m crazy and that with this approach, you’ll never know which exceptions you’re actually catching anymore. You could be right. Opinions differ.

    But that’s OK. All I’m doing is providing an alternative approach to the handling of multiple exception – one that I think offers increased power and flexibility. I’m not saying you should take advantage of it. With greater power comes greater responsibility and all that.

    And besides, we still haven’t talked about Linq. An alternative (and attractive) solution to our current fluent interface is to attach a sequence of catch-handlers at once. Something like this:


    // Unfortunately, this won't compile.
    Func<TR> Protect<TR>(Func<TR> it) {
    return
    it.CatchAll(
    (NullReferenceException ex) => … ,
    (InvalidOperationException ex) => … ,
    (FormatException ex) => … );
    }

    However, it’s surprisingly difficult to provide a suitable type for that sequence of catch-handlers – in fact, the C# compiler fails to do so! The problem is that delegates are contravariant in their parameters, which means that a delegate D1 is considered a subtype of delegate D2 if the parameters of D1 are supertypes of the parameters of D2. That’s all a bit abstract, so perhaps an example will help:


    Action<object> d1 = (object o) => {};
    Action<string> d2 = (string s) => {};
    d1 = d2; // This won't compile.
    d2 = d1; // This is OK.

    view raw

    FuncObject.cs

    hosted with ❤ by GitHub

    To make sense of the abstract description above, assume that D1 is Action<object> and D2 is Action<string>. Since the D1 parameter (object) is a supertype of the D2 parameter (string), it follows that D1 is a subtype of D2 – and not the other way around, as we might have guessed. This is why the C# compiler won’t let us assign a D2 instance to a D1 reference.

    The implication is that the C# compiler will fail to find a type that will reconcile the catch handlers above. In particular, due to the contravariance of delegate parameters, we cannot type the sequence as Func<Exception, TR>, since neither Func<NullReferenceException, TR>, nor Func<InvalidOperationException, TR>, nor Func<FormatException, TR> are assignable to Func<Exception, TR>. It would go the other way around: we could assign a Func<Exception, TR> to all three of the other types, but which one should the compiler pick? If it (arbitrarily) picked Func<NullReferenceException, TR>, clearly it wouldn’t work for the two other delegates – and all other choices have the same problem.

    So we’re stuck. Sort of. The only solution we have is to hide the exception type somehow, so that we don’t have to include the exception type in the type of the sequence. Now how do we do that? Well, in some sense, we’ve already seen an example of how to do that: we hide the exception handling (and the type) inside a closure. So all we need is some way to convert an exception handler to a simple transformation function that doesn’t care about the type of the exception itself. Like this:


    Func<Func<TR>, Func<TR>> Encapsulate<TR, TE>(Func<TE, TR> h)
    where TE : Exception
    {
    return f => () =>
    {
    try {
    return f();
    }
    catch (TE ex) {
    return h(ex);
    };
    };
    }

    view raw

    Encapsulate.cs

    hosted with ❤ by GitHub

    So what is this thing? It’s a method that encapsulates the catch-handler inside a closure. This closure will take as input a closure of type Func<TR> and produce as output another closure of type Func<TR>. In the process, we have hidden the type TE, so that the C# compiler doesn’t have to worry about it anymore: all we have is a thing that will transform a Func<TR> to another Func<TR>.

    So now we can sort of accomplish what we wanted, even though it’s less than perfect.


    Func<TR> Protect<TR>(Func<TR> it) {
    return
    it.CatchAll(
    Encapsulate((NullReferenceException ex) => …),
    Encapsulate((InvalidOperationException ex) => …),
    Encapsulate((FormatException ex) => … ));
    }

    But now we can have some fun using Linq’s Aggregate method to compose our exception handlers. So we might write code like this:


    var catchers = new [] {
    Encapsulate((ArgumentException x) => x.Message),
    Encapsulate((InvalidOperationException x) => { Log(x.Message); throw x; },
    Encapsulate((NullReferenceException x) => "Uh oh")
    };
    var protect = catchers.Aggregate((acc, nxt) => thing => nxt(acc(thing)));
    var f = protect(() => FetchStringSomewhere());
    var s = f();

    The cool part is obviously the Aggregate call, where acc is the “accumulated” composed closure, nxt is the next encapsulated exception handler and thing is the thing we’re trying to protect with our exception handlers – so in other words, the closure that contains the call to FetchStringSomewhere.

    And of course we can now implement CatchAll if we want to:


    static class CatchExtensions
    {
    Func<TR> CatchAll<TR>(
    this Func<TR> f,
    params Func<Func<TR>, Func<TR>>[] catchers)
    {
    var protect = catchers.Aggregate((acc, nxt) => thing => nxt(acc(thing)));
    return protect(f);
    }
    }

    Now please, if you are Eric Lippert and can come up with code that proves that I’m wrong with respect to the typing of sequences of exception handler delegates – please let me know! I would very much like to be corrected if that is the case.