199

To throw exceptions, I usually use built-in exception classes, e.g. ArgumentNullException and NotSupportedException. However, sometimes I need to use a custom exception and in that case I write:

class SlippedOnABananaException : Exception { }
class ChokedOnAnAppleException : Exception { }

and so on. Then I throw and catch these in my code. But today I came across the ApplicationException class - should I be using that instead? What's it for?

It does seem inefficient to have lots of effectively identical Exception classes with different names (I don't usually need any individual functionality). But I dislike the idea of catching a generic ApplicationException and having to use extra code to determine what the error was.

Where should ApplicationException fit in with my code?

James
  • 7,343
  • 9
  • 46
  • 82
  • Related: http://stackoverflow.com/questions/16603065/applicationexception-or-create-custom-exceptions. –  Jul 24 '14 at 17:26

3 Answers3

180

The short answer is: nowhere.

It is a relic of the past, where Microsoft intended developers to inherit all their custom exceptions from ApplicationException. Shortly after, they changed their mind and advised that custom exceptions should derive from the base Exception class. See Best Practices for Handling Exceptions on MSDN.

One of the more widely circulated reasons for this comes from an exerpt from Jeffery Richter in Framework Design Guidelines:

System.ApplicationException is a class that should not be part of the .NET Framework. The original idea was that classes derived from SystemException would indicate exceptions thrown from the CLR (or system) itself, whereas non-CLR exceptions would be derived from ApplicationException. However, a lot of exception classes didn't follow this pattern. For example, TargetInvocationException (which is thrown by the CLR) is derived from ApplicationException. So, the ApplicationException class lost all meaning. The reason to derive from this base class is to allow some code higher up the call stack to catch the base class. It was no longer possible to catch all application exceptions.

So there you have it. The executive summary is that ApplicationException is not harmful, just useless.

Quick Joe Smith
  • 8,074
  • 3
  • 29
  • 33
  • 12
    BTW, it seems from this explanation that this is not a bad design per se but that MSFT screwed up the implementation. Does anyone else read this similarly? – Josh Kodroff Jul 10 '12 at 16:26
  • 10
    @JoshKodroff: I think the issue is that if application `Whizbang` decides that it wants to have all its exceptions under some common hierarchy, using `ApplicationException` for that purpose would really offer no advantage over using a custom `WhizbangException` base class. The more serious problem in .net's exception hierarchy isn't with `ApplicationException`, though, but with the failure to separate exceptions into probably-application-fatal, probably-thread-fatal, and local-problem-related categories, along with an inability to have meaningful "composite" exceptions. – supercat Jul 10 '12 at 16:50
  • @JoshKodroff: In a properly-designed exception framework, IMHO, if an exception gets thrown during `finally` block while another exception is pending, `catch` blocks further up the call stack should be triggered if they match *any* nested exception, but leave other exceptions pending so that exiting a `catch` block would proceed to another `catch` block within the same `try` block (if any were suitable), and exiting a `finally` block with any exceptions pending would jump to the next outer `catch` or `finally`. – supercat Jul 10 '12 at 16:58
  • 2
    @JoshKodroff There is one more thing which I'm surprised don't get more attention. What is an "application" really? What about third-party _libraries_? Since these are not part of the .Net framework, they should by the original guidelines inherit from ApplicationException. Now when you use that library in your application and also creates you own ApplicationExceptions, you can no longer discern your own exceptions from the library's exception based on that. So it's useless. Instead, each component should simply define their own exception base type, as supercat describes. – Oskar Berggren Mar 15 '17 at 22:34
  • 1
    More importantly, who cares whether the exception was thrown by the CLR or the application? That is not a useful distinction. A `FileNotFoundException` is very much a problem that should be reported to the user, but is thrown by the CLR, while an `ArgumentNullException` in my own parameter validation is not thrown by the CLR, but still means "programmer screwed up". – Sebastian Redl Nov 08 '17 at 13:31
  • > "However, a lot of exception classes didn't follow this pattern. For example, TargetInvocationException..." The same story with `System.ComponentModel.DataAnnotations.ValidationException` which I used to use as user errors :-) – ADM-IT May 29 '18 at 22:36
119

According to the remarks in msdn:

User applications, not the common language runtime, throw custom exceptions derived from the ApplicationException class. The ApplicationException class differentiates between exceptions defined by applications versus exceptions defined by the system.

If you are designing an application that needs to create its own exceptions, you are advised to derive custom exceptions from the Exception class. It was originally thought that custom exceptions should derive from the ApplicationException class; however in practice this has not been found to add significant value. For more information, see Best Practices for Handling Exceptions.

Derive them from Exception. Also, I don't see a problem with creating new exceptions for your cases, as long as it is warranted. If you encounter a case where there is already an exception in the framework, use that, otherwise, roll your own.

Community
  • 1
  • 1
Femaref
  • 60,705
  • 7
  • 138
  • 176
27

In the initial design, in .NET 1.0, it was planned that the framework itself will throw SystemException and derived; while user applications - will throw ApplicationException and derived.

But later, in .NET 2.0, that was dropped.

Thus derive from Exception.

abatishchev
  • 98,240
  • 88
  • 296
  • 433