Exception Handling
Lesson 10 • Intermediate Track
Handle errors gracefully with try-catch-finally, create custom exceptions, and write robust C# code.
What You'll Learn
- • Use
try-catch-finallyto handle runtime errors - • Catch specific exception types for targeted handling
- • Create custom exceptions for your domain logic
- • Use
TryParseto avoid exceptions for expected failures - • Apply exception filters with the
whenkeyword
Real-World Analogy
Exception handling is like a safety net at a circus. The trapeze artist (your code) performs risky moves. If they fall, the net (catch) catches them safely. The cleanup crew (finally) always cleans up afterward, whether the act went perfectly or not.
Running C# Locally: Install the .NET SDK or use dotnetfiddle.net.
try-catch-finally
The try block contains code that might fail. catch blocks handle specific errors. The finally block always executes — perfect for closing files, database connections, or releasing resources.
Basic try-catch-finally
See how different exception types are caught and handled.
using System;
class Program
{
static void Main()
{
// Basic try-catch
try
{
Console.Write("Enter a number: ");
int number = int.Parse("abc"); // This will fail!
Console.WriteLine($"You entered: {number}");
}
catch (FormatException ex)
{
Console.WriteLine($"❌ Invalid format: {ex.Message}");
}
catch (OverflowException ex)
{
Console.WriteLine($"❌ Number too la
...Custom Exceptions
For domain-specific errors, create custom exceptions that carry extra context. Inherit from Exception and add properties that help the caller understand what went wrong.
Custom Exception — BankAccount
Create an InsufficientFundsException with balance and amount details.
using System;
// Custom exception for domain-specific errors
class InsufficientFundsException : Exception
{
public decimal Balance { get; }
public decimal Amount { get; }
public InsufficientFundsException(decimal balance, decimal amount)
: base($"Cannot withdraw {amount:C}. Balance is only {balance:C}.")
{
Balance = balance;
Amount = amount;
}
}
class BankAccount
{
public string Owner { get; }
public decimal Balance { get; private set; }
...Common Mistakes
- • Catching Exception too broadly: Always catch the most specific exception type first. Generic
catch (Exception)should be last. - • Swallowing exceptions: Empty
catch {}blocks hide bugs. Always log or handle the error. - • Using exceptions for control flow: Use
TryParseinstead of catchingFormatExceptionfor user input.
TryParse Pattern — Avoid Unnecessary Exceptions
Exceptions are expensive. When you expect invalid input (user data, file content), use the TryParse pattern instead of try-catch. It returns false instead of throwing.
TryParse — Safe Parsing
Parse strings to numbers and dates without throwing exceptions.
using System;
class Program
{
static void Main()
{
// ❌ Bad: Using exceptions for flow control
string input1 = "42";
string input2 = "hello";
// ✅ Good: Use TryParse to avoid exceptions
if (int.TryParse(input1, out int number1))
Console.WriteLine($"Parsed successfully: {number1}");
else
Console.WriteLine("Failed to parse input1");
if (int.TryParse(input2, out int number2))
Console.WriteLine($"P
...Exception Filters (when)
C# 6+ lets you add conditions to catch blocks using the when keyword. The exception is only caught if the condition is true — great for filtering by error codes or messages.
Exception Filters & Retry Pattern
Use 'when' to filter exceptions and implement a retry pattern.
using System;
using System.Net.Http;
class Program
{
static void Main()
{
// Exception filters with 'when' keyword
int errorCode = 404;
try
{
throw new Exception($"HTTP Error {errorCode}");
}
catch (Exception ex) when (ex.Message.Contains("404"))
{
Console.WriteLine("🔍 Resource not found (404)");
}
catch (Exception ex) when (ex.Message.Contains("500"))
{
Console.WriteLin
...Pro Tips
- 💡 Use
throw;(without argument) to re-throw and preserve the original stack trace. - 💡 Prefer
TryParseover try-catch for parsing user input — it's 100x faster. - 💡 Custom exceptions should include useful properties (error codes, context data).
- 💡 The
finallyblock is guaranteed to run — use it for resource cleanup.
Lesson Complete! 🎉
You now know how to handle errors like a pro. Next up: querying data elegantly with LINQ.
Sign up for free to track which lessons you've completed and get learning reminders.