87

In C# how do I define my own Exceptions?

David Basarab
  • 72,212
  • 42
  • 129
  • 156
  • 7
    Kudos (but no +1) for asking an intelligible question with as few words as possible. – Binary Worrier Feb 04 '10 at 14:19
  • I agree with all the answers below, but would like to comment that you should always inherit directly from System.ApplicationException. The MS guideline for this is to distinguish immediately between system exceptions and user-defined exceptions. Whichever you pick, write your baseclass and keep exception usage consistent. – Joel Etherton Feb 04 '10 at 14:38
  • @Joel - Careful what you say. The Microsoft Best Practices document contradict themselves in regards to custom exceptions. I changed my answer because the OP's use seems more geared towards an ApplicationException. Check this post about the contradictions: http://weblogs.asp.net/erobillard/archive/2004/05/10/129134.aspx – Justin Niessner Feb 04 '10 at 14:53
  • Related: https://stackoverflow.com/questions/94488/what-is-the-correct-way-to-make-a-custom-net-exception-serializable It provides instructions on how to make exceptions serializable, but by providing an example it actually answers this question as well. – relatively_random Sep 29 '21 at 07:30

7 Answers7

100

Guidelines for creating your own exception (next to the fact that your class should inherit from exception)

  • make sure the class is serializable, by adding the [Serializable] attribute
  • provide the common constructors that are used by exceptions:

    MyException ();
    
    MyException (string message);
    
    MyException (string message, Exception innerException);
    

So, ideally, your custom Exception should look at least like this:

[Serializable]
public class MyException : Exception
{
    public MyException ()
    {}

    public MyException (string message) 
        : base(message)
    {}

    public MyException (string message, Exception innerException)
        : base (message, innerException)
    {}    
}

About the fact whether you should inherit from Exception or ApplicationException: FxCop has a rule which says you should avoid inheriting from ApplicationException:

CA1058 : Microsoft.Design :
Change the base type of 'MyException' so that it no longer extends 'ApplicationException'. This base exception type does not provide any additional value for framework classes. Extend 'System.Exception' or an existing unsealed exception type instead. Do not create a new exception base type unless there is specific value in enabling the creation of a catch handler for an entire class of exceptions.

See the page on MSDN regarding this rule.

Caleb Jares
  • 6,163
  • 6
  • 56
  • 83
Frederik Gheysels
  • 56,135
  • 11
  • 101
  • 154
45

It seems that I've started a bit of an Exception sublcassing battle. Depending on the Microsoft Best Practices guide you follow...you can either inherit from System.Exception or System.ApplicationException. There's a good (but old) blog post that tries to clear up the confusion. I'll keep my example with Exception for now, but you can read the post and chose based on what you need:

http://weblogs.asp.net/erobillard/archive/2004/05/10/129134.aspx

There is a battle no more! Thanks to Frederik for pointing out FxCop rule CA1058 which states that your Exceptions should inherit from System.Exception rather than System.ApplicationException:

CA1058: Types should not extend certain base types


Define a new class that inherits from Exception (I've included some Constructors...but you don't have to have them):

using System;
using System.Runtime.Serialization;

[Serializable]
public class MyException : Exception
{
    // Constructors
    public MyException(string message) 
        : base(message) 
    { }

    // Ensure Exception is Serializable
    protected MyException(SerializationInfo info, StreamingContext ctxt) 
        : base(info, ctxt)
    { }
}

And elsewhere in your code to throw:

throw new MyException("My message here!");

EDIT

Updated with changes to ensure a Serializable Exception. Details can be found here:

Winterdom Blog Archive - Make Exception Classes Serializable

Pay close attention to the section about steps that need to be taken if you add custom Properties to your Exception class.

Thanks to Igor for calling me on it!

Wiseguy
  • 20,522
  • 8
  • 65
  • 81
Justin Niessner
  • 242,243
  • 40
  • 408
  • 536
  • @Robin ...thanks for the edit. I went back in after I realized I forget to format as code and it was already fixed. – Justin Niessner Feb 04 '10 at 14:18
  • 3
    @Justin Niessner: You have to make your custom exception serializable if you want to be able to throw it across AppDomains – Igor Korkhov Feb 04 '10 at 14:35
  • 1
    It is not recommended to inherit from ApplicationException. It increases your inheritance hierarchy for no good reason. see http://blogs.msdn.com/brada/archive/2004/03/25/96251.aspx and http://blogs.msdn.com/kcwalina/archive/2006/06/23/644822.aspx – Venr Feb 04 '10 at 14:53
  • @Venr - Since MS always in conflicting on this issue, I usually use the guidelines found at http://weblogs.asp.net/erobillard/archive/2004/05/10/129134.aspx – Justin Niessner Feb 04 '10 at 14:57
  • If you store your custom exception data in the exception.Data collection, you can avoid the hassle associated with custom properties & serialization. – Gabe Moothart Feb 04 '10 at 15:03
  • 2
    @Gabe Moothart: "you can avoid the hassle associated with custom properties & serialization" -- only if your custom properties are 'automatically' serializable, i.e. CLR knows how to serialize it – Igor Korkhov Feb 04 '10 at 15:18
  • 2
    MS is not conflicting in their guidelines regarding from which type you should inherit custom exceptions. Before .NET2.0 they advised to inherit from ApplicationException. Since .NET2.0, they advise to inherit from Exception. There's even an FxCop rule that enforces this. (see my answer on this question) – Frederik Gheysels Feb 04 '10 at 16:43
  • 2
    BTW there's a snippet for a constructor in VS's IntelliSense. All it takes is writing "Exception" and pressing tab twice. It has what the constructor in this answer has and a little bit more. – MasterMastic Nov 14 '12 at 22:25
  • FYI: Serializable attribute is not supported for PCL. – Pavel Voronin Dec 21 '14 at 18:07
13

To define:

public class SomeException : Exception
{
    // Add your own constructors and properties here.
}

To throw:

throw new SomeException();
Will Vousden
  • 32,488
  • 9
  • 84
  • 95
8

From Microsoft's .NET Core 3.0 docs:

To define your own exception class:

  1. Define a class that inherits from Exception. If necessary, define any unique members needed by your class to provide additional information about the exception. For example, the ArgumentException class includes a ParamName property that specifies the name of the parameter whose argument caused the exception, and the RegexMatchTimeoutException property includes a MatchTimeout property that indicates the time-out interval.

  2. If necessary, override any inherited members whose functionality you want to change or modify. Note that most existing derived classes of Exception do not override the behavior of inherited members.

  3. Determine whether your custom exception object is serializable. Serialization enables you to save information about the exception and permits exception information to be shared by a server and a client proxy in a remoting context. To make the exception object serializable, mark it with the SerializableAttribute attribute.

  4. Define the constructors of your exception class. Typically, exception classes have one or more of the following constructors:

  • Exception(), which uses default values to initialize the properties of a new exception object.

  • Exception(String), which initializes a new exception object with a specified error message.

  • Exception(String, Exception), which initializes a new exception object with a specified error message and inner exception.

  • Exception(SerializationInfo, StreamingContext), which is a protected constructor that initializes a new exception object from serialized data. You should implement this constructor if you've chosen to make your exception object serializable.

Example:

using System;
using System.Runtime.Serialization;

[Serializable()]
public class NotPrimeException : Exception
{
   private int _notAPrime;
   public int NotAPrime { get { return _notAPrime; } }

   protected NotPrimeException() : base()
   { }

   public NotPrimeException(int value) : base(String.Format("{0} is not a prime number.", value))
   {
      _notAPrime = value;
   }

   public NotPrimeException(int value, string message) : base(message)
   {
      _notAPrime = value;
   }

   public NotPrimeException(int value, string message, Exception innerException) : base(message, innerException)
   {
      _notAPrime = value;
   }

   protected NotPrimeException(SerializationInfo info, StreamingContext context) : base(info, context)
   { }
}

Usage in throw:

throw new NotPrimeException(prime, "This is not a prime number."));

Usage in try/catch:

try
{
   ...
}
catch (NotPrimeException e)
{
   Console.WriteLine( "{0} is not prime", e.NotAPrime );
}
Pavel Anikhouski
  • 21,776
  • 12
  • 51
  • 66
Jpsy
  • 20,077
  • 7
  • 118
  • 115
3

Definition:

public class CustomException : Exception
{
   public CustomException(string Message) : base (Message)
   {
   }
}

throwing:

throw new CustomException("Custom exception message");
SimpleButPerfect
  • 1,529
  • 2
  • 11
  • 20
1

You can create custom exception by using "Exception" class as base class

public class TestCustomException: Exception
{  

  public TestCustomException(string message, Exception inner)
    : base(message, inner)
  {

  } 
}

Complete Console Example

class TestCustomException : Exception
{

    public TestCustomException(string message) : base(message)
    {
        this.HelpLink = "Sample Link details related to error";
        this.Source = "This is source of Error";
    }

}

class MyClass
{
    public static void Show()
    {
        throw new TestCustomException("This is Custom Exception example in C#");
    }
}
class Program
{
    static void Main(string[] args)
    {
        try
        {
            MyClass.Show();
        }
        catch (TestCustomException ex)
        {
            Console.WriteLine("Error Message:-" + ex.Message);
            Console.WriteLine("Hyper Link :-" + ex.HelpLink);
            Console.WriteLine("Source :- " + ex.Source);
            Console.ReadKey();
        }
    }
}

Source : Creating C# Custom Exception (With Console application example)

Vikas Lalwani
  • 1,041
  • 18
  • 29
0

To create your own exception, you can go with this example:

[Serializable()]
public class InvalidExampleException : System.Exception
{
   public InvalidExampleException() : base() { }
   public InvalidExampleException(string message) : base(message) { }
   public InvalidExampleException(string message, System.Exception inner) : base(message, inner) { }

   protected InvalidExampleException(System.Runtime.Serialization.SerializationInfo info,
    System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}

As said in Microsoft Docs, an exception in c# needs at least those four constructors.

Then, to use this exception in your code, you just have to do:

using InvalidExampleException;
public class test
{
    public int i = 0;

    public void check_i()
    {
        if (i == 0) // if i = 0: error
        {
            // exception
            throw new InvalidExampleException("Index is zero");
        }
    }
}
Adam Perea
  • 320
  • 2
  • 9