Why using blocks swallow exceptions?

1k views Asked by At

I recently ran into a problem with exception handling in using statement. The problem is that exceptions which throws inside 'using block' could swallowed, for example look at code:

class DisposableObject : IDisposable
{
    public void Dispose()
    {
        throw new Exception("dispose");
    }
}

class Program
{
    static void Main()
    {
        try
        {
            using (var obj = new DisposableObject())
            {
                throw new Exception("using");
            }
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

In this example you will see 'dispose' in output, first exception will be ignored and you will never know about it. After some searching i found article https://msdn.microsoft.com/en-us/library/aa355056(v=vs.110).aspx about common mistakes about use using block. But my question isn't about how to avoid exception swallowing, i' want to know why MS decided to unwrap using block to

try
{
...
}
finally
{
}

and not the otherwise, for example they could unwrap using to something like this:

//this code prevents exception swallowing
try
{                       
    ...
}
catch (Exception ex)
{
    try
    {
        if (obj != null)
            obj.Dispose();
    }
    catch (Exception disposeEx)
    {
        throw new AggregateException(ex, disposeEx);
    }

    throw;
}
if(obj != null)
    obj.Dispose();
1

There are 1 answers

2
SLaks On

Because AggregateException didn't exist when the using() block was created.

Also because Dispose() is really not supposed to throw.

Finally, because there are subtle semantic differences between your example and a finally block, with regard to exception filters, stack unwinding, and critical regions.