Skip to content
Exception Handling
step 1/7

Reading — step 1 of 7

Learn

~3 min readInheritance, Interfaces, and Exceptions

C# exceptions follow the Java/CLR model — try/catch/finally with typed exception classes. The Microsoft docs cover this thoroughly; this lesson hits the patterns you'll use daily.

try / catch / finally

try
{
    var data = File.ReadAllText("config.json");
    var config = JsonSerializer.Deserialize<Config>(data);
}
catch (FileNotFoundException ex)
{
    Console.Error.WriteLine($"config missing: {ex.Message}");
    return DefaultConfig;
}
catch (JsonException ex)
{
    Console.Error.WriteLine($"bad json: {ex.Message}");
    throw;                    // re-throw
}
catch (Exception ex)
{
    Console.Error.WriteLine($"unexpected: {ex.Message}");
    throw;
}
finally
{
    Cleanup();                // always runs
}
  • Multiple catch clauses — most-specific first
  • finally runs regardless — success, caught exception, uncaught exception
  • Bare throw re-raises preserving the original stack trace
  • throw ex resets the stack trace (almost always wrong)

Throwing exceptions

if (string.IsNullOrEmpty(name))
    throw new ArgumentException("name cannot be empty", nameof(name));

if (age < 0)
    throw new ArgumentOutOfRangeException(nameof(age), age, "age must be non-negative");

nameof(name) produces the string "name" — type-safe, refactor-friendly.

Common BCL exceptions:

  • ArgumentException, ArgumentNullException, ArgumentOutOfRangeException — bad parameters
  • InvalidOperationException — object in wrong state for the call
  • NotSupportedException — operation not supported by this implementation
  • NotImplementedException — placeholder during development
  • IOException, FileNotFoundException — I/O errors

Custom exceptions

public class ValidationException : Exception
{
    public string Field { get; }
    
    public ValidationException(string field, string message) : base(message)
    {
        Field = field;
    }
    
    public ValidationException(string field, string message, Exception inner)
        : base(message, inner)
    {
        Field = field;
    }
}

throw new ValidationException("email", "must contain @");

Convention: name ends in Exception. Always provide a string-message constructor AND a string-message + inner-exception constructor (for wrapping). Inherit from Exception.

Filter clauses (C# 6+)

try
{
    DoWork();
}
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
    HandleNotFound();
}
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.Unauthorized)
{
    HandleAuth();
}

The when clause is evaluated WITHOUT unwinding the stack. Different from rethrowing in the body — preserves the exception's original location for debugging.

using statement — auto-dispose

using (var stream = File.OpenRead("data.bin"))
{
    // use stream
}    // stream.Dispose() called automatically, even if exception

// C# 8+ using declaration:
using var stream = File.OpenRead("data.bin");
// disposes when the enclosing scope ends

Any type implementing IDisposable can be used. Replaces the verbose try/finally for cleanup.

try / async

try
{
    var result = await SomeAsyncOperation();
}
catch (OperationCanceledException)
{
    Console.WriteLine("cancelled");
}
catch (Exception ex)
{
    Console.WriteLine($"failed: {ex.Message}");
}

Exception handling works seamlessly with async/await. The compiler unwraps AggregateException for awaited tasks, so you catch the inner exception directly.

Common mistakes

  • Catching Exception indiscriminately — hides bugs. Catch specific types when you can react meaningfully.
  • Empty catch blocks — silent swallowing of errors. At minimum, log.
  • throw ex; instead of throw; — resets the stack trace. Use bare throw to preserve it.
  • Throwing string messages — must throw an exception object. throw "oops"; is a compile error.
  • Using exceptions for control flow — exceptions are slow and obscure intent. Use Try patterns (int.TryParse) for expected failures.
  • Forgetting using for IDisposables — leaks file handles, network connections, etc.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…