पाठ 20 / 25
Exceptions
Throw, catch and design exceptions without hiding bugs.
Exceptions are for exceptional cases
An exception signals that a method cannot do what its name promises. Throw built-in types where they fit (ArgumentException, ArgumentNullException, InvalidOperationException, KeyNotFoundException), and the guard helpers such as ArgumentNullException.ThrowIfNull(x) keep checks short. Catch an exception only where you can handle it: retry, fall back, translate it into a meaningful error, or log it at a boundary. Catch specific types before general ones, and use exception filters (catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound)) to catch conditionally. To rethrow, write throw;, which preserves the original stack trace; throw ex; resets it and hides where the error started. finally runs whether or not an exception occurred. Do not use exceptions for normal control flow: expected outcomes such as invalid user input are better served by TryParse-style methods or result types.
Good and bad exception handling
Only catch what you can handle; let the rest reach a global handler.
async Task<Product?> LoadProductAsync(string id, CancellationToken ct)
{
ArgumentException.ThrowIfNullOrWhiteSpace(id);
try
{
return await _api.GetProductAsync(id, ct);
}
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
return null; // an expected case, handled
}
catch (HttpRequestException ex)
{
_logger.LogWarning(ex, "Catalogue call failed for {ProductId}", id);
throw; // keep the original stack trace
}
}
// avoid:
// try { ... } catch (Exception) { } // swallows every bug silentlyA fire alarm, not a doorbell
Exceptions are fire alarms: loud, expensive and reserved for real emergencies. Using them to announce visitors (expected situations) means people stop paying attention, and the cost adds up.
त्वरित जाँच: Why prefer `throw;` over `throw ex;` when rethrowing?
- throw; is faster to type
- throw ex; does not compile
- throw; converts the exception to a warning
- throw; preserves the original stack trace
Answer
throw; preserves the original stack trace — throw ex; resets the stack trace to the current location, hiding the real origin.