Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why using blocks swallow exceptions?

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();
like image 327
Oleg Avatar asked Sep 28 '22 12:09

Oleg


1 Answers

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.

like image 119
SLaks Avatar answered Oct 13 '22 01:10

SLaks