// Exercise 2: exception filters + throw; vs throw e; (medium) // // Implement: // - ClassifyRequest(int statusCode): throws a RequestFailedException // carrying that status code. Catch it with exception filters (`when`) // so that: 429 -> "rate limited", 500-599 -> "server error", // anything else -> "client error". Return the matching string. // // - RethrowPreservingTrace(): calls Deep() (throws InvalidOperationException // from inside Deep) inside a try/catch, and re-throws using `throw;` // (NOT `throw e;`) so the ORIGINAL stack trace — including the frame // for "Deep" — survives to the caller. // // Run with: dotnet run (inside a console project) or paste into a Main method. using System; class RequestFailedException : Exception { public int StatusCode { get; } public RequestFailedException(int statusCode) : base($"status {statusCode}") { StatusCode = statusCode; } } class Program { static void ClassifyRequestThrows(int statusCode) { throw new RequestFailedException(statusCode); } #pragma warning disable IDE0060 static string ClassifyRequest(int statusCode) { // TODO: call ClassifyRequestThrows(statusCode) inside a try, and // use exception filters to catch RequestFailedException e: // when (e.StatusCode == 429) -> return "rate limited" // when (e.StatusCode >= 500 && e.StatusCode <= 599) -> return "server error" // (no filter, catch-all RequestFailedException) -> return "client error" return ""; } #pragma warning restore IDE0060 static void Deep() { throw new InvalidOperationException("deep failure"); } static void RethrowPreservingTrace() { try { Deep(); } catch (InvalidOperationException) { // TODO: re-throw using `throw;` (bare, no expression) so the // original stack trace (including the Deep() frame) is kept. } } static void Main() { int pass = 0, total = 0; total++; if (ClassifyRequest(429) == "rate limited") { Console.WriteLine("PASS: 429 classified as rate limited"); pass++; } else Console.WriteLine("FAIL: 429 classified as rate limited"); total++; if (ClassifyRequest(503) == "server error") { Console.WriteLine("PASS: 503 classified as server error"); pass++; } else Console.WriteLine("FAIL: 503 classified as server error"); total++; if (ClassifyRequest(404) == "client error") { Console.WriteLine("PASS: 404 classified as client error"); pass++; } else Console.WriteLine("FAIL: 404 classified as client error"); total++; try { RethrowPreservingTrace(); Console.WriteLine("FAIL: expected InvalidOperationException to propagate"); } catch (InvalidOperationException e) { if (e.StackTrace != null && e.StackTrace.Contains("Deep")) { Console.WriteLine("PASS: original stack trace preserved through throw;"); pass++; } else Console.WriteLine("FAIL: stack trace lost — did you use `throw e;` instead of `throw;`?"); } Console.WriteLine($"--- {pass}/{total} checks passed ---"); } }