What happens if the filter of an Exception filter throws an exception

If there is an exception thrown within the filter, then that exception will be silently swallowed and the filter simply fails. This causes the original exception to go down the catch cases or ultimately end up being reraised upwards.

So the code calling the filter will not have a way to know that there was actually an exception within your filter method. Thus, it’s important to avoid conditions where an exception can be thrown to make sure that a filter doesn’t fail for this reason.

You can verify this using the following code on volatileread.com’s C# 6 beta interpreter:

public void Main ()
{
    try
    {
        try
        {
            throw new Exception("Original exception");
        }
        catch (Exception ex)
            when (Test()) // `if (Test())` in older previews
        {
            Console.WriteLine("Caught the exception");
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e);
    }
}

public static bool Test ()
{
    throw new Exception("Exception in filter condition");
}

This results in the “Original exception” appearing in the outer try/catch block.


Update

Since I didn’t understand the output from volatileread’s compiler when not using the outer try/catch block, I installed the MS Build Tools 2015 myself (which as of the time of this answer still uses if, not when) and tried it out. It turns out that when not using the outer try/catch, the “original exception” is still the one that causes the program to crash. So it’s not the filter exception. This seems to be a bug with volatile’s compiler.


Edit: The oddness seems to be caused by a bug in volatileread. Please refer to poke's answer. The experiments below can not be trusted

So I ran a few experiments that gave a few interesting results to shed some light on the issue.

Check using http://volatileread.com/utilitylibrary/snippetcompiler?id=7632

public void Main()
{
  try
  {
    throw new Exception("Forced Exception");
  }
  catch (Exception ex) when (MethodThatThrowsAnException())
  {
    Console.WriteLine("Filtered handler 1");
  }
  catch (Exception ex)
  {
    Console.WriteLine("Filtered handler 2");
  }
}

private bool MethodThatThrowsAnException()
{
  throw new Exception();   
}

Prints out "Filtered handler 2"

public void Main()
{
  try
  {
    throw new Exception("Forced Exception");
  }
  catch (Exception ex) when (MethodThatThrowsAnException())
  {
    Console.WriteLine("Filtered handler 1");
  }

}

private bool MethodThatThrowsAnException()
{
  throw new Exception("MethodThatThrowsAnException");   
}

Prints out:

Unhandled Expecption: System.Exception: MethodThatThrowsAnException
at Program.MethodThatThrowsAnException() at Program.Main()

Another interesting output for

   public void Main()
    {
      try
      {
        throw new Exception("Forced Exception");
      }
      catch (Exception ex) when(MethodThatThrowsAnException())
      {
        Console.WriteLine("Filtered handler 1");
      }
      catch (Exception ex) when(MethodThatThrowsAnException2())
      {
        Console.WriteLine("Filtered handler 2");

      }
    }

    private bool MethodThatThrowsAnException()
    {
      throw new Exception("MethodThatThrowsAnException");   
    }

    private bool MethodThatThrowsAnException2()
    {
      throw new Exception("MethodThatThrowsAnException2");   
    }

Unhandled Expecption: System.Exception: MethodThatThrowsAnException2 at Program.MethodThatThrowsAnException2() at Program.Main()

So it seems like it tries to evaluated the first catch if it throws an exception it continues to the next catch. The first catch that does not fail and matches all conditions then handles the exception (BTW an exception of the type originally thrown in the try). However if the last catch that is of the type of the thrown error also throws an exception in the filter part then an Unhandled Exception is thrown of the type in the filter.

Edit: Note:

public void Main()
{
  try
  {
    try
    {
      throw new Exception("Forced Exception");
    }
    catch (Exception ex) when (MethodThatThrowsAnException())
    {
      Console.WriteLine("Filtered handler 1");
    }
  }
  catch (Exception ex)
  {
      Console.WriteLine("Caught");
      Console.WriteLine(ex);
  }
}

private bool MethodThatThrowsAnException()
{
  throw new Exception("MethodThatThrowsAnException");   
}

Outputs:

Caught

System.Exception: Forced Exception at Program.Main()

If you compare that with the second output... HOW THE HELL IS THAT POSSIBLE??? In the second example MethodThatThrowsAnException is thrown but in the last example "Forced Exception" is caught


You can try it out here.

As @Habib correctly indicates, the filter simply gets skipped and it's as if it never existed. From that point on, the catch clauses work as they always have. The example above demonstrates this.

However if you change the second catch clause to a type that cannot catch whatever is thrown from your method, your program will crash because of an unhandled exception.

Spicy detail (bug): if you call the method encompassing the try-catch via reflection and a when clause throws an exception then it will be this exception that is considered unhandled and not the original one. More information here.

Tags:

C#

C# 6.0