Exception handling is the process of responding to exceptions – a situation which occurs during the application execution that disrupts the normal program flow (think of them loosely as errors in code). The C# programming language provides the Exception class and its entire hierarchy to handle exceptions in your applications gracefully.
In this programming tutorial, we will take an in-depth look at exceptions and how they can be handled in C# using the Exceptions class.
Read: Productivity Tools for .NET Developers
What is an Exception in C#?
An exception is a runtime error (i.e., an error that occurs when the program is in execution). When an exception occurs, the runtime terminates the flow of the program, (i.e., the program comes to an abrupt halt) unless the exception is handled in the source code.
Programmers can write custom code to handle exceptions that might occur when your application is in execution. To do this, you should use the Exception class or any of the classes in the Exception class hierarchy.
Why Are Exceptions Needed?
Exceptions help to create a better user experience by allowing the program to respond more gracefully to errors. The developers can quickly identify what went wrong and retrieve detailed information about the error by using exceptions to take corrective action.
Exceptions also help developers find and fix errors faster by providing easy-to-understand messages and stack traces that show where the exception occurred in the code. This enables developers to understand the root cause of an exception quickly and efficiently, as well as identify potential corrective measures.
Some of the common exception classes in the exception hierarchy in C# include the following:
- System.Exception
- System.ArithmeticException
- System.IO.IOException
- System.IndexOutOfRangeException
- System.NullReferenceException
- System.DivideByZeroException
- System.InvalidCastException
- System.OutOfMemoryException
You can learn more about exception handling, in general, in our tutorial: Exception Handling in C#.
What is the Exception Class in C#?
The Exception class is one of the most widely used types in the C# programming language. The Exception class provides several methods and properties that allow programmers to obtain information about the current exception, including the stack trace and the inner exception.
This metadata can help you debug an error and determine the cause of the error with ease. You can take advantage of the Exception class to catch and respond to any exceptions that might occur in your application.
The Exception class is the base type of all exception types in C# language. The following code example shows how to use the System.Exception class:
public class Exception : System.Runtime.Serialization.ISerializable { //Members of the System.Exception class }
How Does The Exception Class Work in C#?
When an exception is thrown in C#, the common language runtime (CLR) creates an Exception object that contains the error and the related metadata, such as the name of the assembly, the class name, the stack trace, and so forth.
When a matching catch block is found, the statements inside that catch block are executed. If no matching catch block is available, the execution of the program halts thereafter and the appropriate error message is displayed.
You can learn more about classes and how they function in our tutorial: Introduction to Classes in C#.
Exception Blocks in C#
The most common way to handle exceptions in C# is to use a try/catch block. It should be noted that the keywords try, catch, finally, and throw are used to work with exceptions in C#. The keywords try, catch, and finally are collectively known as exception blocks since they contain a block of statements.
Consider the following piece of code demonstrating how to use a try/catch block in C#:
try { //Typically, this block contains code that might throw an exception } catch (Exception ex) { //This block contains the necessary code to handle the exception Console.WriteLine(ex.Message); } finally { //This block contains the necessary code to perform clean-up activities }
Typically, a programmer might want to write code such as opening database connections, file handles, etc. in the try block. Remember, if any of these activities fail, an exception will be thrown by the runtime.
In the catch block, you should handle the exception or propagate it appropriately. In the preceding code example, the exception generated in the try block is swallowed in the catch block and the exception message is displayed at the console window.
The finally block should contain code to clean-up or release activities, such as closing a database connection, file handle, etc.
Note that the finally block is optional (i.e., if you have a try block you must have one or more catch blocks and, optionally, a finally block) as demonstrated in the following code example:
int x = 0; try { int y = 10 / x; } catch (ArithmeticException ae) { Console.WriteLine($"ArithmeticException Occurred: {ae}"); } catch (Exception ex) { Console.WriteLine($"Generic Exception Occurred: {ex}"); }
Custom Exception Class in C#
The Exception class allows you to create custom exception classes to provide more specific error handling capabilities, giving you more control over how exceptions are handled in your application.
When creating a custom exception, developers can extend their custom exception class from either the Exception class or one of its child classes and attach additional functionality. Additionally, you should consider all potential use-cases and plan out which error codes and messages should be included in the custom exception.
Programmers can create their custom exception class by inheriting the ApplicationException class. However, it is always a good practice to extend the System.Exception class while creating a custom exception class.
This is because the runtime will never throw an instance of ApplicationException when an exception occurs in your application. Instead, it will throw an instance of either System.Exception or any of its sub-classes.
You can extend the ApplicationException class to create a custom exception class only if you would like to rethrow the exception after optionally appending additional information to it.
The following code sample shows how a typically custom exception class is written in C#:
public class DbException : System.Exception { public DbException() : base() { } public DbException(String message) : base(message) { } public DbException(String message, Exception innerException) : base(message, innerException) { } protected DbException(SerializationInfo info, StreamingContext context) : base(info, context) { } }
Best practices for Using Exceptions in C#
There are a few best practices you should adhere to when working with exceptions in C#. The first rule says that you should not catch general exceptions; instead, it is always a good practice to catch specific exceptions to help you handle each exception type appropriately.
The second rule is to never swallow an exception without understanding why you are doing it. By swallowing an exception, programmers catch it but do not do anything with it, which can hide bugs and make them more challenging to trace.
As a third tip, you should always log exceptions when they occur. This will help you to troubleshoot issues more effectively. Last but not least, do not use exceptions to control flow. It is not recommended to use exceptions to control the flow of your program but only to deal with exceptional circumstances.
Final Thoughts on the C# Exception Class
The Exception class in C# is an incredibly useful class that can help you manage errors gracefully so that you can provide a better user experience while avoiding potential crashes or data loss.
With proper use of the Exception class, developers can ensure that your applications are more robust and user-friendly. This programming tutorial has provided an overview of exceptions, exception handling, and how to work with the Exception class in C#.
Read more C# programming tutorials and software development guides.