Smuggling exceptions out of try-catches with IEnumerable

Posted on |

The code in this post is from a talk by Erik Meijer, I claim no credit.

Take a look at this screenshot:

Exception thrown from try-catch

Pretty wacky huh? Visual Studio has broken into debug mode even though the division is clearly wrapped in a try-catch. Take a guess at what’s going on before reading on.

Here’s the full code listing:

static void Main(string[] args)
{
    var xs = new[] { 1, 2, 3, 0 };
    IEnumerable q = null;

    try
    {
        q = from x in xs select 1 / x;
    }
    catch { }

    foreach (var z in q)
    {
        Console.WriteLine(z);
    }
}

The obvious expectation is that division-by-zero will be caught by the try-catch. Alas, the division does not happen in the scope of the try statement. Instead, due to the deferred execution paradigm of IEnumerable, it happens on a by-need basis in the for-loop. From there the exception can propogate unopposed to the top af the stack. Haskell, where lazy evaluation dominates, avoids exceptions (and other messy side effects) alltogether, partly for reasons demonstrated by this example.

UPDATE: As Wayne points out, fixing this is as easy as extending the try to cover the enumeration. The point of this post was mainly to poke fun at the Visual Studio debugger and to point out that lazy evaluation can bite you if you’re not careful.

3 thoughts on “Smuggling exceptions out of try-catches with IEnumerable”

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>