CHAPTER 7 UNDERSTANDING STRUCTURED EXCEPTION HANDLING
Note In practice, few .NET developers build custom exceptions that extend ApplicationException. Rather, it
is more common to simply subclass System.Exception; however, either approach is technically valid.
Building Custom Exceptions, Take One
While you can always throw instances of System.Exception to signal a runtime error (as shown in the
first example), it is sometimes advantageous to build a strongly typed exception that represents the
unique details of your current problem. For example, assume you want to build a custom exception
(named CarIsDeadException) to represent the error of speeding up a doomed automobile. The first step
is to derive a new class from System.Exception/System.ApplicationException (by convention, all
exception classes end with the “Exception” suffix; in fact, this is a .NET best practice).
Note As a rule, all custom exception classes should be defined as public classes (recall, the default access
modifier of a non-nested type is internal). The reason is that exceptions are often passed outside of assembly
boundaries, and should therefore be accessible to the calling code base.
Create a new Console Application project named CustomException, and copy the previous Car.cs
and Radio.cs files into your new project using the Project Add Existing Item menu option (for clarity, be
sure to change the namespace that defines the Car and Radio types from SimpleException to
CustomException). Next, add the following class definition:
// This custom exception describes the details of the car-is-dead condition.
// (Remember, you can also simply extend Exception.)
public class CarIsDeadException : ApplicationException
{}
As with any class, you are free to include any number of custom members that can be called within
the catch block of the calling logic. You are also free to override any virtual members defined by your
parent classes. For example, we could implement the CarIsDeadException by overriding the virtual
Message property.
As well, rather than populating a data dictionary (via the Data property) when throwing our
exception, our constructor allows the sender to pass in a time stamp and reason for the error. Finally, the
time stamp data and cause of the error can be obtained using strongly typed properties:
public class CarIsDeadException : ApplicationException
{
private string messageDetails = String.Empty;
public DateTime ErrorTimeStamp {get; set;}
public string CauseOfError {get; set;}
public CarIsDeadException(){}
public CarIsDeadException(string message,
string cause, DateTime time)
{
267