Exception Handling — The City's Disaster Recovery
20 XPMedium
Ctrl+Enter RunCtrl+S Save
🛡️ Exception Handling in C#
Even the best-planned cities face disasters — earthquakes, fires, budget overruns. A well-governed city doesn't pretend bad things won't happen; it builds disaster recovery systems.
In C#, exceptions are the runtime's way of saying "something went wrong." Exception handling gives you structured tools to catch errors, recover gracefully, and clean up resources.
🧱 try / catch / finally
try — wraps code that might throw an exception.
catch — handles the exception if one occurs.
finally — runs always, whether or not an exception was thrown. Perfect for cleanup.
For domain-specific errors, create your own exception class by inheriting from Exception:
class PermitExpiredException : Exception
{
public PermitExpiredException(string message) : base(message) { }
public PermitExpiredException(string message, Exception inner)
: base(message, inner) { }
}
🚨 throw vs throw ex
throw; — rethrows the current exception, preserving the original stack trace.
throw ex; — resets the stack trace to the current point. Avoid this — it destroys debugging information.
throw new CustomException("msg", ex); — wraps the original exception as an inner exception. Best practice for custom exceptions.
📐 The Exception Hierarchy
All exceptions inherit from System.Exception. Catch more specific exceptions first, then more general ones. Catching bare Exception is a last resort — it catches everything, including critical system errors you shouldn't swallow.
try { /* ... */ }
catch (FileNotFoundException ex) { /* specific */ }
catch (IOException ex) { /* less specific */ }
catch (Exception ex) { /* last resort */ }
finally { /* always runs */ }
📋 Instructions
**The City's Disaster Recovery System**
Build a program that demonstrates exception handling:
1. Print `"Attempting construction..."`
2. In a `try` block, throw a new `InvalidOperationException("Budget exceeded!")`
3. `catch` it and print `"Error caught: Budget exceeded!"`
4. Print `"Recovery: Adjusting budget..."`
5. In the `finally` block, print `"Finally: Cleanup complete"`
6. After the try/catch/finally, create a second try/catch:
- Throw a new `PermitExpiredException("Permit has expired")`
- Catch `PermitExpiredException` and print `"Custom error: PermitExpiredException handled"`
Define `PermitExpiredException` as a class inheriting from `Exception` with a constructor that takes a `string message`.
Define `class PermitExpiredException : Exception` with a constructor passing `message` to `base(message)`. In Main, use try { throw new InvalidOperationException(...); } catch (InvalidOperationException ex) { print message + recovery } finally { print cleanup }. Then a second try/catch for the custom exception.