Best practices in handling exceptions in C#

Take advantage exception handling and use it judiciously to handle runtime errors in your application

Best practices in exception handling

Best practices in exception handling

Exception handling is the technique of handling runtime errors in your application code. Basically, you have two categories of exceptions: Exceptions that are generated by the application and those that are generated by the runtime. Exceptions should be handled with care -- you should have a good idea of how exceptions should be handled and when they are needed to be handled in your code. In this post, I will present a few tips and best practices for working with exceptions in C#.

The base class for all exceptions in .NET is Exception. All exception classes in the exception hierarchy derive directly or indirectly from this class. The ApplicationException and SystemException classes are derived from the Exception class. The Common Language Runtime (CLR) throws an instance of a type that is derived from SystemException when an error occurs at runtime. Note that you should never catch SystemException or throw an instance of SystemException in your application's code.
When creating custom exception classes, always derive from the Exception class and not from the ApplicationException class. One of the reasons for this is that an instance of ApplicationException is thrown by the application and never by the runtime. In throwing an instance of ApplicationException in your code, you would just increase the call stack without adding much value.

It is a bad design approach to use exception handling to return information from a method. If you are returning exception data from your method, your class design is wrong and should be revisited. Note that exceptions are bubbled up to the higher level in the method call hierarchy and it is not a good practice to handle exceptions in all the layers of your application. You should handle an exception as higher up in the call hierarchy as you can -- you can consume an exception in the presentation layer and display appropriate messages to the user to notify the exact error that has occurred.

Re-throwing an exception is needed when you would like to rollback a database transaction. It is a good practice to use specific exceptions like FileNotFoundException, IOException, etc. when writing exception handlers and then a general catch block at the end with the Exception class. This would ensure that you get to know the exact error or the specific error that has occurred. The MSDN states: "The ApplicationException class does not provide information as to the cause of exceptions. In most scenarios, instances of this class should not be thrown. In cases where this class is instantiated, a human-readable message describing the error should be passed to the constructor."

You should use try - catch blocks to handle exceptions and use a finally block to clean up the resources used in your program. The try block would contain code that might raise an exception, the catch block will be used to handle the exception thrown inside the try block and the finally block will be used to deallocate any resources the program has used. Note that the finally block is guaranteed to be executed irrespective of whether an exception has occurred or not. Hence, finally block is the best place in your code for cleaning up the resources your program has used.

The code snippet below shows how the "using" statement can be used to dispose resources. Note that the "using" statement is an equivalent of try - finally block.

public string Read(string fileName)
{
try
{
string data;
using (StreamReader streamReader = new StreamReader(fileName))
{
data = streamReader.ReadToEnd();
}
return data;
}
catch (Exception)
{
throw;
}
}
Throwing exceptions is expensive. It is a bad practice to rethrow exceptions - in rethrowing exceptions you would loose the stack trace.
try
{
//Some code that might throw an exception
}
catch(Exception ex)
{
throw ex;
}
Instead, just use the statement "throw" if you would like not to handle the exception in your exception handler and propagate the exception upwards in the call hierarchy.
try
{
//Some code that might throw an exception
}
catch(Exception ex)
{
throw;
}
Never swallow exceptions -- you should never hide the error that has occurred. It is a good practice to log exceptions in your application. When logging exceptions, you should always log the exception instance so that the complete stack trace is logged and not the exception message only. Here is an example that illustrates this.
try
{
//Some code that might throw an exception
}
catch(Exception ex)
{
LogManager.Log(ex.ToString());
}
You should never use exceptions to propagate or execute business rules in your application. You can avoid exceptions in your code by using proper validation logic. Exceptions should in most cases be avoided -- you should use it only when it is needed.
You can refer to this MSDN article for more information.

This article is published as part of the IDG Contributor Network. Want to Join?

From CIO: 8 Free Online Courses to Grow Your Tech Skills
Notice to our Readers
We're now using social media to take your comments and feedback. Learn more about this here.