Designing Custom Exceptions

Switch View :
ScriptFree
.NET Framework Developer's Guide 
Designing Custom Exceptions 

The following guidelines help ensure that your custom exceptions are correctly designed.

Avoid deep exception hierarchies.

For more information, see Types and Namespaces.

Do derive exceptions from System.Exception or one of the other common base exceptions.

Note that Catching and Throwing Standard Exception Types has a guideline that states that you should not derive custom exceptions from ApplicationException.

Do end exception class names with the Exception suffix.

Consistent naming conventions help lower the learning curve for new libraries.

Do make exceptions serializable. An exception must be serializable to work correctly across application domain and remoting boundaries.

For information about making a type serializable, see Serialization.

Do provide (at least) the following common constructors on all exceptions. Make sure the names and types of the parameters are the same those used in the following code example.

C#
public class NewException : BaseException, ISerializable
{
    public NewException()
    {
        // Add implementation.
    }
    public NewException(string message)
    {
        // Add implementation.
    }
    public NewException(string message, Exception inner)
    {
        // Add implementation.
    }

    // This constructor is needed for serialization.
   protected NewException(SerializationInfo info, StreamingContext context)
   {
        // Add implementation.
   }
}

Do report security-sensitive information through an override of System.Object.ToString only after demanding an appropriate permission. If the permission demand fails, return a string that does not include the security-sensitive information.

Do store useful security-sensitive information in private exception state. Ensure that only trusted code can get the information.

Consider providing exception properties for programmatic access to extra information (besides the message string) relevant to the exception.

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

Community Content

TAG
Additional properties defined in exception must be stored on serialization

Please note that any additional properties must be serialized in GetObjectData() method from ISerializable interface.

 

Here is sample code:

using System;
using System.Runtime.Serialization;

[Serializable]
public class CustomException : Exception, ISerializable
{
    private readonly string myCustomProperty;

    public string MyCustomProperty { get { return myCustomProperty; } }

    public CustomException()
    {
        myCustomProperty = "Default";
    }

    public CustomException(string message, string customProperty)
        : base(message)
    {
        myCustomProperty = customProperty;
    }

    public CustomException(string message, Exception inner, string customProperty)
        : base(message, inner)
    {
        myCustomProperty = customProperty;
    }

    protected CustomException(SerializationInfo info, StreamingContext context)
        // Make sure to call base method as it can put some own information
        : base(info, context)
    {
        // And read back your value - failure to do will make your property having default value (null or 0)
        myCustomProperty = info.GetString("MyCustomProperty");
    }

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        // Make sure to call base method as it can read own information
        base.GetObjectData(info, context);
        // Store value using format that can be decoded later
        // Make is recomended to select in such a way that no sub-classes will take over it by accident
        info.AddValue("MyCustomProperty", myCustomProperty);
    }
}