| File I/O in C# | Serialization and deserialization in C# | |
🛠️ Exception Handling & Logging in C# |
Exception handling and logging are crucial for building robust and maintainable C# applications. Exception handling deals with runtime errors and allows the application to recover gracefully, while logging records events and exceptions for monitoring and debugging.
Exception handling allows your application to gracefully respond to unexpected errors. Logging helps you record those errors for diagnostics and monitoring. Together, they form the backbone of robust and maintainable applications.
try {
// Code that may throw an exception
}
catch (InvalidOperationException ex) {
Console.WriteLine("Handled specific exception: " + ex.Message);
}
catch (Exception ex) {
Console.WriteLine("General exception: " + ex.Message);
}
finally {
Console.WriteLine("Cleanup code always runs.");
}
finally or using blocks to release resources.throw; instead of throw ex;.
public static class Logger {
public static void LogError(Exception ex, string message) {
Console.WriteLine("❌ Error: " + message);
Console.WriteLine("Details: " + ex.Message);
}
}
try {
// Risky code
}
catch (Exception ex) {
Logger.LogError(ex, "Something went wrong");
}
try/catch inside async methods.catch when) for conditional handling.using System;
using System.IO;
public class FileProcessor
{
public void ReadFile(string path)
{
StreamReader? reader = null;
try
{
reader = new StreamReader(path);
string content = reader.ReadToEnd();
Console.WriteLine(content);
}
catch (FileNotFoundException ex)
{
// Log the specific exception
Console.WriteLine($"Error: The file '{path}' was not found.");
// Good practice: log the full exception details
LogException(ex);
}
catch (Exception ex)
{
// Catch other, less specific exceptions and re-throw
Console.WriteLine("An unexpected error occurred.");
LogException(ex);
throw; // Re-throw to propagate to the caller
}
finally
{
// The finally block ensures the resource is cleaned up
if (reader != null)
{
reader.Dispose();
}
}
}
private void LogException(Exception ex)
{
// Placeholder for logging
Console.WriteLine($"LOG: An exception of type {ex.GetType().Name} occurred.");
Console.WriteLine($"LOG: Message: {ex.Message}");
Console.WriteLine($"LOG: Stack Trace: {ex.StackTrace}");
}
}
using for objects that implement IDisposable to ensure proper cleanup.throw; instead of throw ex; to preserve the original stack trace.Logging is the practice of recording important events and data during an application's execution. It provides a historical record for diagnostics, performance monitoring, and compliance. The modern .NET logging framework uses the ILogger interface.
dotnet add package Microsoft.Extensions.Logging.Console
using Microsoft.Extensions.Logging;
public class MyService
{
private readonly ILogger _logger;
public MyService(ILogger<MyService> logger)
{
_logger = logger;
}
public void DoWork(int value)
{
_logger.LogInformation("Starting work on value: {Value}", value);
if (value < 0)
{
_logger.LogWarning("Negative value passed: {Value}", value);
}
try
{
if (value == 13)
{
throw new ArgumentException("Value 13 is considered bad luck.");
}
_logger.LogInformation("Work completed successfully.");
}
catch (Exception ex)
{
_logger.LogError(ex, "An error occurred during work with value {Value}", value);
}
}
}
public class Program
{
public static void Main(string[] args)
{
using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Information);
});
var service = new MyService(loggerFactory.CreateLogger<MyService>());
service.DoWork(5);
service.DoWork(-1);
service.DoWork(13); // This will trigger the exception
}
}
Exception handling and logging are essential for building reliable and maintainable C# applications. By following best practices and using the right tools, you can ensure your app recovers gracefully and provides meaningful insights when things go wrong.
| File I/O in C# | Serialization and deserialization in C# | |