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.