C# Exception Handling
1. What is exception handling in C#?
Definition: Exception handling is a mechanism used to handle runtime errors without abruptly terminating the application.
C# provides try, catch, finally, and throw keywords to handle exceptions.
Example Program
try
{
int a = 10;
int b = 0;
int result = a / b;
Console.WriteLine(result);
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Cannot divide by zero.");
}
Output:
Cannot divide by zero.
Explanation
-
The
tryblock contains code that may throw an exception. -
Division by zero throws
DivideByZeroException. -
The
catchblock handles the exception. -
The application can continue executing after the exception is handled.
Flow Diagram
Start
|
v
try block
|
v
Exception?
/ \
No Yes
| |
v v
Continue catch block
| |
+----+----+
|
v
Next Statement
Key Points
-
Exceptions represent errors or unexpected conditions during execution.
-
Exception handling prevents unhandled exceptions from terminating the application.
-
Common exceptions include:
-
NullReferenceException -
DivideByZeroException -
IndexOutOfRangeException -
FormatException -
SqlException
-
-
Catch specific exceptions whenever possible.
-
In ASP.NET Core Web API, centralized exception handling is commonly implemented using middleware or
IExceptionHandler.
2. What is the difference between throw and throw ex?
Definition: Both statements rethrow an exception, but they differ in how they preserve the exception's stack trace.
-
throw;preserves the original stack trace. -
throw ex;resets the stack trace at the rethrow location, losing important original call-site information.
Example Program
public static void Divide()
{
int a = 10;
int b = 0;
Console.WriteLine(a / b);
}
public static void Calculate()
{
try
{
Divide();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw; // Preserves original stack trace
}
}
Usage:
try
{
Calculate();
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
Explanation
When Divide() throws an exception, Calculate() catches it.
Using throw;:
Exception
|
v
Divide() <-- Original error location
|
v
Calculate()
|
v
throw;
|
v
Original stack trace preserved
Using throw ex;:
Exception
|
v
Divide() <-- Original error location
|
v
Calculate()
|
v
throw ex;
|
v
Stack trace restarted at rethrow
Original call-site information lost
Differences
|
Feature |
|
|
|---|---|---|
|
Purpose |
Rethrow current exception |
Throw exception object again |
|
Stack trace |
Preserves original trace |
Resets trace at rethrow |
|
Debugging |
Easier |
More difficult |
|
Recommended |
Yes |
Avoid for rethrowing |
|
Usage |
Inside |
Where exception variable is available |
Key Points
-
Prefer
throw;when rethrowing an exception inside acatchblock. -
throw ex;makes debugging harder by losing original stack trace information. -
Use
throw new Exception(...)when intentionally creating a new exception. -
You can use
throw new CustomException("Message", ex)to wrap an exception while retaining the original asInnerException.
Interview Tip: Always use throw; instead of throw ex; when you want to preserve the original exception stack trace.
3. What is the purpose of try, catch, and finally?
Definition:
-
try: Contains code that may throw an exception. -
catch: Handles an exception thrown from thetryblock. -
finally: Executes cleanup code whether an exception occurs or not, including when an exception is not caught locally.
Example Program
try
{
Console.WriteLine("Try started");
int a = 10;
int b = 0;
Console.WriteLine(a / b);
}
catch (DivideByZeroException ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
finally
{
Console.WriteLine("Finally executed");
}
Output:
Try started
Exception: Attempted to divide by zero.
Finally executed
Explanation
-
The
tryblock starts execution. -
Division by zero throws an exception.
-
The
catchblock handles the exception. -
The
finallyblock executes after exception handling. -
Execution continues after the entire construct.
Flow Diagram
Start
|
v
try block
|
v
Exception?
/ \
No Yes
| |
| v
| catch block
| |
+-----+----+
|
v
finally block
|
v
Continue Execution
If an exception is not handled, finally normally executes before the exception propagates to the caller.
Key Points
-
A
tryblock must be followed by at least onecatchor afinallyblock. -
Multiple
catchblocks can handle different exception types. -
Specific exception types should be caught before general exception types.
-
The
finallyblock is commonly used for cleanup operations. -
finallynormally executes even whenreturnis used insidetryorcatch. -
Execution of
finallyis not guaranteed during abrupt process termination. -
Prefer
usingorawait usingfor disposing resources that implementIDisposableorIAsyncDisposable.
Quick Interview Revision
|
Concept |
Important Point |
|---|---|
|
Exception handling |
Handles runtime errors |
|
|
Contains potentially failing code |
|
|
Handles matching exceptions |
|
|
Performs cleanup |
|
|
Preserves original stack trace |
|
|
Resets stack trace at rethrow |
|
Multiple |
Handles different exception types |
|
Global exception handling |
Centralizes exception processing in ASP.NET Core |
Real-world ASP.NET Core Web API: Use global exception handling for unexpected errors, logging, and consistent HTTP error responses. Use local try-catch blocks when the application can meaningfully recover, retry, or translate an exception.