This project is read-only.
1

Resolved

Exceptions thrown from an exception filter should be catchable or halt application execution

description

It appears that if an exception is thrown in the exception filter block, there is no way to catch that exception. Additionally, the application continues on as if that exception was never thrown.

This code example outputs "caught E2", but I would expect something similar to this (similar to throwing an exception within a catch block): "System.Exception: Test at Program.Main()".
public void Main()
{
  try
  { 
    throw new Exception("E2");
  }
  catch(Exception ex) if (Test()) // Exception is thrown here
  {
    Console.WriteLine("Test");
  }
  catch(Exception ex) if(ex.Message == "E1")
  {
    Console.WriteLine("caught E1");
  }
  catch(Exception ex) if(ex.Message == "E2") // this block runs
  {
    Console.WriteLine("caught E2");
  }
}

public bool Test()
{
  throw new Exception("Fake");
  return true;
}

comments

PauloMorgado wrote Jan 4, 2015 at 7:15 PM

Why do you think it should?

Although strange, it does exactly what it already was doing in VB12.

The following VB12 code behaves just the same:
Sub Main()

    Try

        Throw New Exception("E2")

    Catch ex As Exception When Test()

    Catch ex As Exception When Test()

        Console.WriteLine("Test")

    Catch ex As Exception When ex.Message = "E1"

        Console.WriteLine("caught E1")

    Catch ex As Exception When ex.Message = "E2"

        Console.WriteLine("caught E2")

    End Try
End Sub

Function Test() As Boolean

    Throw New Exception("Fake")

End Function

aholmes0 wrote Jan 4, 2015 at 7:51 PM

I'm only familiar with C#, though my understanding is the IL has supported this for a long time. I suppose if VB behaves as such, then it's not really a bug, but perhaps it's an oversight.

That said, I think it should throw the new exception as a guarantee that possible application errors aren't buried like this. I imagine this could cause certain bugs to be very difficult to figure out, or could even completely break some error handling.

For example, say the erroring method was meant to log exceptions. If you attached a debugger to figure out why error messages were no longer writing, your debugger would never stop on the log method, and may not stop at all.

PauloMorgado wrote Jan 4, 2015 at 8:25 PM

I tottaly understand why one teoreticaly would expect what you were expecting. I also would expect the same thing.

This feature was annonced as parity to Visual Basic, whch doesn't mean that it should be exactly the same.

I though you had found some contratidtion between the implementation and the spec.

aholmes0 wrote Jan 4, 2015 at 9:07 PM

I should clarify that by "though my understanding is the IL has supported this for a long time" I meant "the IL has supported VB's behavior for a long time."

VSadov wrote Jan 7, 2015 at 8:32 PM

This is by design. It is basically how exception filters work in IL.

Filters can only result in EXCEPTION_EXECUTE_HANDLER or EXCEPTION_CONTINUE_SEARCH and runtime treats exceptions thrown by the filters the same as EXCEPTION_CONTINUE_SEARCH.

This behavior is at the lower level than C# language.