46

Is there any way in C# (i.e. in .NET) to throw a custom exception but without writing all the code to define your own exception class derived from Exception?

I am thinking something similar you have for example in Oracle PL/SQL where you can simply write

raise_application_error(-20001, 'An arbitary error message');

at any place.

Dan Beaulieu
  • 19,406
  • 19
  • 101
  • 135
Wernfried Domscheit
  • 54,457
  • 9
  • 76
  • 110
  • You can add custom properties to a custom exception class, so couldn't you just make one custom exception class, then add an Enum for the "type" of exception? – mellamokb May 01 '15 at 20:14
  • 7
    If `throw new Exception("An arbitary error message");` won't work for you, it might be a good idea to extend a question to explain why. – DK. May 01 '15 at 20:15
  • No, There isn't and there shouldn't be. – Zohar Peled May 01 '15 at 20:25
  • @ZoharPeled What's your rationale for saying that? – mason May 01 '15 at 20:35
  • @mason: My rational is very simple: Exceptions carry a lot more information then just a simple message. they carry the stack trace, they can carry an inner exception, etc. PL/SQL raise error does not. Another reason is that raising an error message without using an Exception object goes agains the normal exception pattern, and .Net does not provide a try...catch mechanism for that. ( – Zohar Peled May 02 '15 at 04:44

5 Answers5

84
throw new Exception("A custom message for an application specific exception");

Not good enough?

You could also throw a more specific exception if it's relevant. For example,

throw new AuthenticationException("Message here");

or

throw new FileNotFoundException("I couldn't find your file!");

could work.

Note that you should probably not throw new ApplicationException(), per MSDN.

The major draw back of not customizing Exception is that it will be more difficult for callers to catch - they won't know if this was a general exception or one that's specific to your code without doing some funky inspection on the exception.Message property. You could do something as simple as this:

public class MyException : Exception
{
    MyException(int severity, string message) : base(message)
    {
        // do whatever you want with severity
    }
}

to avoid that.

Update: Visual Studio 2015 now offers some automatic implementation of Exception extension classes - if you open the Quick Actions and Refactoring Menu with the cursor on the : Exception, just tell it to "Generate All Constructors".

Dan Field
  • 20,885
  • 5
  • 55
  • 71
  • 2
    You shouldn't use the `ApplicationException` class, see the remarks here: https://msdn.microsoft.com/en-us/library/system.applicationexception%28v=vs.110%29.aspx – Ron Beyer May 01 '15 at 20:15
  • ApplicationException is effectively deprecated. – Orion Adrian May 01 '15 at 20:16
  • This is not a "Custom" exception as the OP asked. However, I'm more interested in understanding this statement: "_Note that you should probably not throw new Exception(), as that can cause other problems._" - can you explain further? – Metro Smurf May 01 '15 at 20:17
  • Sorry about that, got them mixed up! Switched around now. – Dan Field May 01 '15 at 20:17
  • 3
    @MetroSmurf think about it, its an exception without *any information what-so-ever* about what happened. On top of that, its impossible to handle without handling every exception (`catch Exception` instead of `catch SpecificException`). – Ron Beyer May 01 '15 at 20:18
  • I did not notice (although it is obvious), that `throw new Exception` is overloaded and that you can pass custom error message. – Wernfried Domscheit May 02 '15 at 08:29
  • Don't throw System.Exception, System.SystemException, System.NullReferenceException, or System.IndexOutOfRangeException intentionally from your own source code. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/exceptions/creating-and-throwing-exceptions#things-to-avoid-when-throwing-exceptions https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/using-standard-exception-types – huang Jan 28 '21 at 18:37
12

The Exception class is not an abstract, and like most of the exceptions defined in .NET, takes a string message in one of the constructor overloads - you can therefore use an existing exception type, but with a customized message.

throw new Exception("Something has gone haywire!");
throw new ObjectDisposedException("He's Dead, Jim");
throw new InvalidCastException(
    $"Damnit Jim I'm a {a.GetType().Name}, not a {b.GetType().Name}!");

Because this uses exception types that are known, it makes it easier for thrid parties to extend your libraries as well, since they don't need to look for MyArbitraryException in catch statements.

David
  • 10,458
  • 1
  • 28
  • 40
4

Short answer - no.

There is a good reason for enforcing the inheritance of custom exceptions; people need to be able to handle them. If you could throw your custom exception without having a type, people wouldn't be able to catch that exception type.

If you don't want to write a custom exception, use an existing exception type.

Fenton
  • 241,084
  • 71
  • 387
  • 401
4

An easy way to create custom Exceptions in c# is using a generic class. This reduces the lines of code dramatically if you need to create much exceptions (i.e. if you need to distinguish between them in your unit tests).

First create a simple class called CustomException<T>:

public class CustomException<T> : Exception where T : Exception
{
    public CustomException() { }
    public CustomException(string message) : base(message){ }
    public CustomException(string message, Exception innerException) : base(message, innerException){ }
    public CustomException(SerializationInfo info, StreamingContext context) : base(info, context){ }
}

You can override as many constructors and methods as you want (or need) to. In order to create new Exception types just add new one-liner classes:

public class MyCustomException : Exception { }
public class SomeOtherException : Exception { }

If you want to raise your custom exception use:

throw new CustomException<MyCustomException>("your error description");

This keeps your Exception code simple and allows you to distinguish between those exceptions:

try
{
    // ...
}
catch(CustomException<MyCustomException> ex)
{
    // handle your custom exception ...
}
catch(CustomException<SomeOtherException> ex)
{
    // handle your other exception ...
}
Mirko
  • 743
  • 1
  • 7
  • 18
3

You can just throw one of the exceptions that is available in .NET:

throw new System.ArgumentException("Parameter cannot be null", "original");

Or more generic:

throw new ApplicationException("File storage capacity exceeded.");
Alex
  • 21,273
  • 10
  • 61
  • 73