Exception Handling

16 questions found

What is the difference between throw and throw ex inside a catch?

Beginner
throw re-throws preserving the original stack trace; throw ex resets the stack trace to the current line, losing where the error really happened.
catch (Exception ex) { Log(ex); throw; }      // good
catch (Exception ex) { throw ex; }             // loses stack trace
Real-world example Preserving the original stack trace is essential for diagnosing production errors.

What is the purpose of the finally block?

Beginner
finally always runs (whether or not an exception occurred) and is used to release resources like files, connections or locks.
try { conn.Open(); ... }
finally { conn.Dispose(); }
Real-world example Ensuring a database connection is closed even if the query throws.

When should you use using or await using?

Intermediate
For IDisposable/IAsyncDisposable resources — they call Dispose/DisposeAsync deterministically at the end of scope, even on exceptions, replacing manual try/finally.
await using var conn = new SqlConnection(cs);
await conn.OpenAsync();
Real-world example Guaranteeing a stream or connection is released promptly rather than waiting for GC.

What are exception filters (when) and why use them?

Intermediate
A when clause lets a catch run only if a condition is true, without unwinding the stack for non-matching cases, which aids logging and selective handling.
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound) { }
Real-world example Handling only 404s from an HTTP call while letting other status codes propagate.

When should you create custom exceptions vs use built-in ones?

Advanced
Create a custom exception when callers need to catch a domain-specific condition distinctly; otherwise reuse built-ins (ArgumentException, InvalidOperationException). Keep a meaningful hierarchy.
public class InsufficientFundsException(decimal shortfall) : Exception;
Real-world example A banking layer throws InsufficientFundsException so the API can map it to a 422 response.

What is the recommended strategy for exceptions in a layered/enterprise app?

Advanced
Throw specific exceptions in lower layers, don't swallow them, translate to a consistent response at the boundary (middleware/ProblemDetails), and log with context. Avoid using exceptions for control flow.
app.UseExceptionHandler();  // central translation to ProblemDetails
Real-world example One middleware converts domain and unexpected exceptions into consistent JSON errors for all API clients.

How does a try/catch block work in C#, and what happens if no matching catch clause exists?

Beginner
Code in the try block runs normally; if it throws, execution jumps immediately to the FIRST matching catch clause (matched by exception type, checked top to bottom) — if no catch clause matches the thrown exception's type, the exception propagates up the call stack, potentially crashing the program if never caught anywhere.
try {
  int result = 10 / int.Parse("0");
} catch (DivideByZeroException ex) {
  Console.WriteLine($"Division error: {ex.Message}");
} catch (FormatException ex) {
  Console.WriteLine($"Format error: {ex.Message}");
}
Real-world example Gracefully handling a parsing error or division-by-zero condition instead of letting the application crash.

Common follow-ups: What happens if you put a more general exception type's catch clause BEFORE a more specific one?

Fundamentals

What does the finally block guarantee, and when is it commonly used?

Beginner
Code in a finally block ALWAYS runs after the try (and any catch) block completes, whether an exception was thrown or not, and even if the try block contains a 'return' statement — making it the standard place for cleanup code like closing files or releasing resources.
FileStream? file = null;
try {
  file = File.OpenRead("data.txt");
  ProcessFile(file);
} finally {
  file?.Dispose(); // always runs, ensuring the file handle is released
}
Real-world example Guaranteeing a database connection or file handle is properly closed regardless of whether the operation succeeded or threw.

Common follow-ups: How does the 'using' statement relate to and often replace a manual try/finally for disposal?

File I/O & Streams

How do custom exception classes work in C#, and what's the recommended convention for creating one?

Intermediate
A custom exception should inherit from Exception (or a more specific built-in exception type), be named ending in 'Exception', and typically provide the standard set of constructors (parameterless, message-only, message+innerException) to remain compatible with standard exception-handling conventions and serialization.
public class InsufficientFundsException : Exception {
  public decimal ShortfallAmount { get; }
  public InsufficientFundsException(decimal shortfall)
    : base($"Insufficient funds. Short by {shortfall:C}.") {
    ShortfallAmount = shortfall;
  }
}
Real-world example Throwing a domain-specific exception (like InsufficientFundsException) that carries meaningful business context beyond a generic message string.

Common follow-ups: Why is it considered good practice to include the standard set of base constructors on a custom exception?

OOP

What is exception filtering using the 'when' clause, and what advantage does it offer over catching and manually re-throwing?

Intermediate
The 'when' clause adds a condition to a catch block that must ALSO be true for that catch to handle the exception — critically, if the condition is false, the exception continues propagating WITHOUT the catch block ever executing, preserving the original stack trace exactly, unlike catching broadly and manually re-throwing based on a condition inside.
try {
  await CallApiAsync();
} catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.TooManyRequests) {
  await Task.Delay(1000);
  await RetryAsync();
}
// Exceptions NOT matching the 'when' condition propagate normally, untouched
Real-world example Handling only a SPECIFIC HTTP status code's exception (like rate limiting) while letting all other HttpRequestExceptions propagate normally.

Common follow-ups: How does exception filtering with 'when' avoid the stack-trace-resetting problem of catch-then-rethrow?

Asynchronous Programming

Showing 1–10 of 16