What is ApplicationException for in .NET?
Asked Answered
C

4

202

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?

Czarevna answered 16/4, 2011 at 10:32 Comment(1)
Related: #16603565.Haff
C
121

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.

Champignon answered 16/4, 2011 at 10:36 Comment(3)
So It seems that ApplicationException is useless and is there merely because of backward compatibility?Ectoplasm
New MSDN documentation, at least 4.7.2, misses this remark. Thanks for the qutoe :DKerge
Did they try to fix this in .NET Core rewrite?Mahatma
S
184

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.

Stableman answered 16/4, 2011 at 10:38 Comment(6)
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?Blackleg
@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.Mirabella
@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.Mirabella
@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.Lustreware
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".Schoenberg
> "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 :-)Burnley
C
121

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.

Champignon answered 16/4, 2011 at 10:36 Comment(3)
So It seems that ApplicationException is useless and is there merely because of backward compatibility?Ectoplasm
New MSDN documentation, at least 4.7.2, misses this remark. Thanks for the qutoe :DKerge
Did they try to fix this in .NET Core rewrite?Mahatma
E
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.

Endomorphic answered 16/4, 2011 at 10:37 Comment(0)
E
0

Coming from the Java world (which pre-dates .Net and defined the ApplicationException), I take a somewhat different view.

As per Java: An application exception shall be thrown when there is a business-logic error, as opposed to a system error.

Application exceptions are sent to the client without being repackaged as an EJBException. Therefore, you can use them to report validation errors or business logic problems, and they will reach the client.

A clear explanation of system exception vs application exception


So in .Net, I use ApplicationExceptions to propagate Business Rules errors up to the Boundary class, which knows how to send them back to the client, such as for an API as a 409, or for an ESB client it knows to send a notification and not to retry the message, as opposed to any System.Exception which can be retried.


In summary, ApplicationException isn't to differentiate application errors from .Net errors, it's to differentiate Business Rule errors that are responsibility of the Client to corrects versus System error that need Bug Triage from support teams.

Eleni answered 23/1 at 16:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.