Home > OS >  C# Exception Handling - will last catch block fetch re-thrown Exception?
C# Exception Handling - will last catch block fetch re-thrown Exception?

Time:10-23

I'm wondering if this code will work in the way that after 10 retries CleanUp() will be called? Or will the throw new Exception() not get caught by the last catch block?

public void Process()
{
    try
    {}
    catch (MyException e)
    {           
        int retries = GetRetries();
        if(retries > 10)
        {
            _logger.LogError("Retried event already {retries} times. Giving up.", retries);
            throw new Exception("Giving up!");
        }

        Process();

    }
    catch (Exception e)
    {
        CleanUp();
    }
}

CodePudding user response:

No, it doesn't work like that. For any given try/catch block, only an exception originating in the try can be caught by the corresponding catch blocks. Exceptions thrown within catch blocks are not catchable by other catch blocks at the same level.

finally blocks allow you to run code when control leaves a try/catch for any reason. So if the end of your try already has a CleanUp then you would just change your final catch(Exception e) to finally and remove the CleanUp at the end of the try part.

If, however, you only want to run CleanUp when control leaves the try/catch via an exception, you're not so lucky. There is a fault clause in IL, which is finally, but only for exceptions, but that's not exposed in C#.

So if you need that, it's usually best to introduce an extra bool that indicates you reached the end of the try block without exception, and use that to make your CleanUp call conditional in the finally.


Or you may simulate try/catch/fault by nesting try/catch blocks:

try
{
    try
    {}
    catch (MyException e)
    {           
        int retries = GetRetries();
        if(retries > 10)
        {
            _logger.LogError("Retried event already {retries} times. Giving up.", retries);
            throw new Exception("Giving up!");
        }

        Process();

    }
}
catch
{
  //Act as fault
  CleanUp();
  throw;
}
  • Related