C# Error Handling

C# reports runtime failures with exceptions. try guards risky code, catch reacts to failures, and finally always cleans up.

Exceptions

try / catch

Catch specific types first; a general Exception catch is the last resort.

try
{
    int divisor = int.Parse("0");
    int result = 10 / divisor;
    Console.WriteLine(result);
}
catch (DivideByZeroException)
{
    Console.WriteLine("Cannot divide by zero.");
}
catch (Exception ex)
{
    Console.WriteLine($"Error: {ex.Message}");
}

finally

finally runs whether or not an exception was thrown — ideal for cleanup.

try
{
    Console.WriteLine("work");
}
catch (Exception ex)
{
    Console.WriteLine(ex.Message);
}
finally
{
    Console.WriteLine("cleanup");
}

throw

throw raises an exception when a method detects an invalid state.

static void CheckAge(int age)
{
    if (age < 0)
        throw new ArgumentOutOfRangeException(nameof(age));
}

Custom Exceptions

Definition

Inherit from Exception to make precise, domain-specific errors.

class ValidationException : Exception
{
    public ValidationException(string message) : base(message) { }
}

Usage

Throw the custom exception where the invalid state is detected; callers can then catch it precisely.

static void Register(string name)
{
    if (string.IsNullOrWhiteSpace(name))
        throw new ValidationException("Name is required.");

    Console.WriteLine($"Registered {name}");
}

Best Practices

Exception Filters

Use a when clause to catch only the failures you can handle.

catch (HttpRequestException ex)
    when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
{
    Console.WriteLine("Resource not found");
}

Do Not Swallow

Never leave an empty catch block. Log or rethrow with throw; to preserve the stack trace.

catch (Exception ex)
{
    Console.WriteLine(ex);
    throw; // rethrow, keep original stack
}