Phase 14 of 30 · Topic 14.2

Exception Filters (`catch (...) when (...)`) vs `throw` Preserving Stack

1Concept

Exception filters evaluate boolean conditions in Phase 1 (the search pass) before the stack is unwound. Rethrowing with `throw;` preserves the original stack trace, whereas `throw ex;` truncates it.

2Architecture Diagram

catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
       │
   Evaluates BEFORE stack unwinds (preserves full original memory state for dump debuggers!)

3Code Example

C# 13 & .NET 9
using System;
using System.Net.Http;
using System.Net;

public class ExceptionFilterDemo
{
    public static void Main()
    {
        try
        {
            ExecuteNetworkCall();
        }
        catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.ServiceUnavailable)
        {
            Console.WriteLine("Filtered Catch: 503 Service Unavailable -> Triggering Circuit Breaker.");
        }
        catch (Exception)
        {
            Console.WriteLine("Generic catch fallback.");
        }
    }

    public static void ExecuteNetworkCall()
    {
        throw new HttpRequestException("Server Offline", null, HttpStatusCode.ServiceUnavailable);
    }
}

4Expected Output

Filtered Catch: 503 Service Unavailable -> Triggering Circuit Breaker.

5Key Takeaways

  • Never write `throw ex;` (it resets the stack trace to the catch block); always write `throw;`.
  • Exception filters allow granular selective catching without entering catch blocks.
  • Filters do not unwind the stack if the condition evaluates to false.