Why exception filters are preferable to catching and rethrowing?

烈酒焚心 提交于 2021-01-28 11:52:29

问题


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@domain.com";
}

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:


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/32638310/why-exception-filters-are-preferable-to-catching-and-rethrowing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!