Basics of Exception Handling
Avoid catching generic exceptions like Exception unless absolutely necessary. Always prefer catching specific exception types.
Using Try/Catch
C# Example
        Copy to clipboard
        
      
try {
    // Code that may throw exceptions
} catch (IOException ex) {
    Console.WriteLine($"I/O error: {ex.Message}");
} catch (UnauthorizedAccessException ex) {
    Console.WriteLine($"Access error: {ex.Message}");
}
    Finally Blocks
Use finally blocks to guarantee resource cleanup regardless of exceptions.
FileStream file = null;
try {
    file = new FileStream("file.txt", FileMode.Open);
    // work with file
} catch (IOException ex) {
    Console.WriteLine(ex.Message);
} finally {
    file?.Close(); // ensures resource release
}
  Using IDisposable Objects
using (var file = new FileStream("file.txt", FileMode.Open)) {
    // Work with the file
} // Automatically disposed
  Logging Exceptions
try {
    // risky code
} catch (Exception ex) {
    Logger.Error(ex, "An error occurred in method X");
}
  Custom Exceptions
public class CustomException : Exception {
    public CustomException(string message) : base(message) { }
}
// Usage
throw new CustomException("A specific error occurred");
  Async Exception Handling
try {
    await SomeAsyncMethod();
} catch (Exception ex) {
    Console.WriteLine($"Async exception: {ex.Message}");
}
  Exception Propagation Across Methods
Handle exceptions at the level where they make sense. Propagate upwards using throw if a method cannot handle them meaningfully.
public void MainMethod() {
    try{
        SpecificMethod();
    } catch (Exception ex){
        Console.WriteLine($"Handled in MainMethod: {ex.Message}");
    }
}
public void SpecificMethod() {
    HelperMethod(); // may throw
}
public void HelperMethod() {
    throw new InvalidOperationException("Something went wrong");
}
  Unit Testing Exceptions
Write unit tests to verify exception handling works as expected.