Which built-in .NET exceptions can I throw from my application?
If I need to throw an exception from within my application which of the built-in .NET exception classes can I use? Are they all fair game? When should I derive my own?
Solution 1:
See Creating and Throwing Exceptions.
On throwing built-in exceptions, it says:
Do not throw System.Exception, System.SystemException, System.NullReferenceException, or System.IndexOutOfRangeException intentionally from your own source code.
and
Do Not Throw General Exceptions
If you throw a general exception type, such as Exception or SystemException in a library or framework, it forces consumers to catch all exceptions, including unknown exceptions that they do not know how to handle.
Instead, either throw a more derived type that already exists in the framework, or create your own type that derives from Exception."
This blog entry also has some useful guidelines.
Also, FxCop code analysis defines a list of "do not raise exceptions" as described here. It recommends:
The following exception types are too general to provide sufficient information to the user:
- System.Exception
- System.ApplicationException
- System.SystemException
The following exception types are reserved and should be thrown only by the common language runtime:
- System.ExecutionEngineException
- System.IndexOutOfRangeException
- System.NullReferenceException
- System.OutOfMemoryException
So in theory you can raise any other framework exception type, providing you clearly understand the intent of the exception as described by Microsoft (see MSDN documentation).
Note, these are "guidelines" and as some others have said, there is debate around System.IndexOutOfRangeException (ie many developers throw this exception).
Solution 2:
On the subject of System.Exception
and System.ApplicationException
: The latter was meant to be used as the base class of all custom exceptions. However, this hasn't been enforced consistently from the beginning. Consequently, there's a controversy whether this class should be used at all rather than using System.Exception
as the base class for all exceptions.
Whichever way you decide, never throw an instance of these two classes directly. It's actually a pity that they aren't abstact
. For what it's worth, always try using the most specific exception possible. If there is none to meet your requirement, feel free to create your own. In this case, however, make sure that your exception has a benefit over existing exceptions. In particular, it should convey its meaning perfectly and provide all the information necessary to handle the situation in a meaningful manner.
Avoid to create stub exceptions that don't do anything meaningful. In the same vein, avoid creating huge exception class hierarchies, they're rarely useful (although I can imagine a situation or two where I would use them … a parser being one of them).
Solution 3:
I use the ArgumentException
(and its “friends”) regularly.
NotSupportedException
and NotImplementedException
are also common.
Solution 4:
My advice would be to focus on two things:
- Scenarios
- User expectations
In otherwords, I would sit down and identify:
- Under what scenarios do you want to throw exceptions.
- In those scenarios, what would the users of your API expect
The answer to #1 is, of course, application specific. The answer to #2 is "what ever similar code they are already familiar with does".
The behavior that comes out of this is:
-
Under the scenarios that arise in your programs that also arrive inside the framework, such as arguments being null, out of range, being invalid, methods not being implemented, or just not supported, then you should use the same exceptions the framework uses. The people using your APIs are going to expect that they behave that way (because that's how everything else behaves), and so will be better able to use your api from the "get go".
- For new scenarios that don't exist in the framework, you should go ahead and invent your own exception classes. I would say that you should prefer Exception as your base class unless their is some other base exception that provides services you need. Generally speaking I don't think something like "ApplicationException" will help you much. When you start defining your own exceptions there are a few things you should keep in mind though:
a. The primary purpose of an exception is for human communication. They convey information about something that happened that shouldn't have. They should provide enough information to identify the cause of a problem and to figure out how to resolve it.
b. Internal consistency is extremely important. Making your app behave as universally as possible under similar circumstances will make you API's users more productive.
As far as there being hard and fast rules about what you should and should not do... I wouldn't worry about that stuff. Instead I would just focus on identifying scenarios, finding the existing exception that fits those scenarios, and then carefully desining your own if an existing one doesn't exist.
Solution 5:
You can create and throw pretty much any of them, but you generally shouldn't. As an example, the various argument validation exceptions (ArgumentException, ArgumentNullException, ArgumentOutOfRangeException, etc) are suitable for use in application code, but AccessViolationException isn't. ApplicationException is provided as a suitable base class for any custom exception classes you may require.
See this MSDN article for a list of best practices - it refers to handling exceptions, but also contains good advice on creating them...