Catching and Throwing Standard Exception Types

The following guidelines describe best practices for some of the most commonly used exceptions provided by the .NET Framework.

Exception and SystemException

Do not throw System.Exception or System.SystemException.

Do not catch System.Exception or System.SystemException in framework code, unless you intend to re-throw.

Avoid catching System.Exception or System.SystemException, except in top-level exception handlers.

ApplicationException

Do derive custom exceptions from the T:System.Exception class rather than the T:System.ApplicationException class.

It was originally thought that custom exceptions should derive from the ApplicationException class; however, this has not been found to add significant value. For more information, see Best Practices for Handling Exceptions.

InvalidOperationException

Do throw a System.InvalidOperationException exception if in an inappropriate state. System.InvalidOperationException should be thrown if a property set or a method call is not appropriate given the object's current state. For example, writing to a System.IO.FileStream that has been opened for reading should throw a System.InvalidOperationException exception.

This exception should also be thrown when the combined state of a set of related objects is invalid for the operation.

ArgumentException, ArgumentNullException, and ArgumentOutOfRangeException

Do throw System.ArgumentException or one of its subtypes if bad arguments are passed to a member. Prefer the most-derived exception type if applicable.

The following code example demonstrates throwing an exception when an argument is null (Nothing in Visual Basic).

If (anObject = Nothing) Then
    Throw New ArgumentNullException("anObject", "Specify a non-null argument.")
End If
if (anObject == null)
{
    throw new ArgumentNullException("anObject",
        "Specify a non-null argument.");
}
if (anObject == nullptr)
{
    throw gcnew ArgumentNullException("anObject",
        "Specify a non-null argument.");
}

Do set the System.ArgumentException.ParamName property when throwing System.ArgumentException or one of its derived types. This property stores the name of the parameter that caused the exception to be thrown. Note that the property can be set using one of the constructor overloads.

Do use value for the name of the implicit value parameter of property setters.

The following code example shows a property that throws an exception if the caller passes a null argument.

Public Property Address() As IPAddress
    Get
        Return IPaddr
    End Get
    Set(ByVal value As IPAddress)
        If IsNothing(value) Then
            Throw New ArgumentNullException("value")
        End If
        IPaddr = value
    End Set
End Property
public IPAddress Address
{
    get
    {
        return address;
    }
    set
    {
        if(value == null)
        {
            throw new ArgumentNullException("value");
        }
        address = value;
    }
}
property IPAddress^ Address
{
    IPAddress^ get()
    {
        return address;
    }
    void set(IPAddress^ value)
    {
        if (value == nullptr)
        {
            throw gcnew ArgumentNullException("value");
        }
        address = value;
    }
}

Do not allow publicly callable APIs to explicitly or implicitly throw System.NullReferenceException, System.AccessViolationException, System.InvalidCastException, or System.IndexOutOfRangeException. Do argument checking to avoid throwing these exceptions. Throwing these exceptions exposes implementation details of your method that may change over time.

StackOverflowException

Do not explicitly throw System.StackOverflowException. This exception should be explicitly thrown only by the common language runtime (CLR).

Do not catch System.StackOverflowException.

It is extremely difficult to programmatically handle a stack overflow. You should allow this exception to terminate the process and use debugging to determine the source of the problem.

OutOfMemoryException

Do not explicitly throw System.OutOfMemoryException. This exception should be thrown only by the CLR infrastructure.

ComException and SEHException

Do not explicitly throw System.Runtime.InteropServices.COMException or System.Runtime.InteropServices.SEHException. These exceptions should be thrown only by the CLR infrastructure.

Do not catch System.Runtime.InteropServices.SEHException explicitly.

ExecutionEngineException

Do not explicitly throw System.ExecutionEngineException.

Portions Copyright 2005 Microsoft Corporation. All rights reserved.

Portions Copyright Addison-Wesley Corporation. All rights reserved.

For more information on design guidelines, see the "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries" book by Krzysztof Cwalina and Brad Abrams, published by Addison-Wesley, 2005.

See Also

Concepts

Choosing the Right Type of Exception to Throw

Other Resources

Design Guidelines for Developing Class Libraries

Design Guidelines for Exceptions