Search code examples
c#throwrethrow

Throw inside Catch in C#


Found something yesterday that made me realise that I'm most likely still missing fundamental tidbits about C#.

I have a Stateless Service Fabric Application. I have a try-catch around the main while-loop. If I throw an exception in this loop, it breaks out of the while-loop and the service effectively stops. If I add a throw to the catch clause, the service restarts.

    protected override async Task RunAsync(CancellationToken cancellationToken)
    {
        try
        {
            long iterations = 0;
            while (true)
            {
                cancellationToken.ThrowIfCancellationRequested();

                await Task.Delay(TimeSpan.FromSeconds(3), cancellationToken).ConfigureAwait(false);

                // Do stuff...

                if (iterations > 4) {
                    throw new Exception();
                } 

                ServiceEventSource.Current.ServiceMessage(this.Context, $"Working-{++iterations}");
            }
        }
        catch (Exception ex)
        {
            // Log stuff...
            throw;
        }
    }

Can someone explain why this is or direct me to where I can get an answer? I couldn't find anything that explain this behaviour.

EDIT: It's not a duplicate of Is there a difference between "throw" and "throw ex"? because, as far as I can see, there it no explanation of my question, why the function is being run again. That topic is more about explaining the difference between throw and throw new respective of the stack trace.


Solution

  • With what you have described, we have two options:

    1. You rethrow the exception and the RunAsync Task is failed with that exception
    2. You don't rethrow the exception and the RunAsync Task is completed gracefully (the caught exception broke the while loop and so the method exits).

    For the first case, the Service Fabric Stateless Service RunAsync doc further details the behavior when an exception is encountered, namely that exceptions derived from FabricException will cause a restart while others are either intended or unexpected service abortion and cause it to stop.

    The graceful completion logically means that the service successfully finished executing and will be shut down as per Service Fabric Reliable Services Lifecycle doc.