Rolando Retana
Rolando Retana

Reputation: 492

Why exception filters are preferable to catching and rethrowing?

Based on this question (What benefit does the new Exception filter feature provide?).

The statement:

Exception filters are preferable to catching and rethrowing because they leave the stack unharmed. If the exception later causes the stack to be dumped, you can see where it originally came from, rather than just the last place it was rethrown.

after doing some testing, I did not see the difference between both, the old and the new, I still see the exception from the place it was rethrown. So, or the information is not confirmed, I don't understand the Exception filters( that is why I am asking), or I am doing it wrong. Can you explaing me why this action filter are an advantage?

class specialException : Exception
{
   public DateTime sentDateTime { get; } = DateTime.Now;
   public int code { get; } = 0;
   public string emailsToAlert { get; } = "[email protected]";
}

then:

        try
        {
            throw new specialException(); //line 16
            throw new Exception("Weird exception");
            //int a = Int32.Parse("fail");
        }
        catch (specialException e) when(e.code == 0)
        {
            WriteLine("E.code 0");
            throw; // <-Line 23
        }
        catch (FormatException e) 
        {
                WriteLine("cond1 " + e.GetBaseException().Message+" "+e.StackTrace);
                throw;
        }
        catch (Exception e) //when (cond2)
        {
            Console.WriteLine("cond2! " + e.Message);
                throw;
        }

Result:

enter image description here

Upvotes: 1

Views: 783

Answers (2)

Cory Nelson
Cory Nelson

Reputation: 30021

I'll give you a good real world example that I've used it for: deadlock retry loops.

Some APIs are nice and have a specific DeadlockException sort of thing -- others, like SOAP proxies, not quite. When you don't have one, exception filters are great to avoid needing to rethrow.

int retryCount = 0;

while(true)
{
    try
    {
        // do stuff.
        break;
    }
    catch(Exception ex) when(ex.Message == "Deadlock" && ++retryCount < 10)
    {
        // retry up to 10 times.
        continue;
    }
}

This saves you from having to throw a wrapper exception if a non-deadlock exception happens, or if the retry limit is hit.

Upvotes: 3

Andy
Andy

Reputation: 30418

The advantages of exception filtering are more to do with when the filter doesn't match, not when it does match. If you remove all of the catch blocks except for the first one, and change the filter on the first catch block to when(e.code != 0), then the callstack of the exception would indicate it was thrown on line 16.

The old way of implementing this would be as follows:

    try
    {
        throw new specialException(); //line 16
        throw new Exception("Weird exception");
        //int a = Int32.Parse("fail");
    }
    catch (specialException e)
    {
        if(e.code != 0)
        {
            WriteLine("E.code isn't 0");
            return;
        }

        throw;
    }

In this case, the call stack will indicate that the exception was thrown at the throw statement, rather than on line 16.

Upvotes: 5

Related Questions