What are some best practices for creating my own custom exception? - c#

In a follow-up to a previous question regarding exceptions, what are best practices for creating a custom exception in .NET?
More specifically should you inherit from System.Exception, System.ApplicationException or some other base exception?

In the C# IDE, type 'exception' and hit TAB. This will expand to get you started in writing a new exception type. There are comments withs links to some discussion of exception practices.
Personally, I'm a big fan of creating lots of small classes, at that extends to exception types. For example, in writing the Foo class, I can choose between:
throw new Exception("Bar happened in Foo");
throw new FooException("Bar happened");
throw new FooBarException();
where
class FooException : Exception
{
public FooException(string message) ...
}
and
class FooBarException : FooException
{
public FooBarException()
: base ("Bar happened")
{
}
}
I prefer the 3rd option, because I see it as being an OO solution.

Inherit from System.Exception. System.ApplicationException is useless and the design guidelines say "Do not throw or derive from System.ApplicationException."
See http://blogs.msdn.com/kcwalina/archive/2006/06/23/644822.aspx

There is a code snippet for it. Use that. Plus, check your code analysis afterwards; the snippet leaves out one of the constructors you should implement.

I think the single most important thing to remember when dealing with exceptions at any level (making custom, throwing, catching) is that exceptions are only for exceptional conditions.

The base exception from where all other exceptions inherit from is System.Exception, and that is what you should inherit, unless of course you have a use for things like, say, default messages of a more specific exception.

Related

Should custom exception classes derive from System.ApplicationException?

https://learn.microsoft.com/en-us/dotnet/api/system.applicationexception?view=net-5.0 says that "ApplicationException Class" Serves as the base class for application-defined exceptions. But in an example at https://learn.microsoft.com/en-us/dotnet/standard/exceptions/how-to-create-user-defined-exceptions custom exception class derives from "Exception" base class.
Well, MSDN states clearly
Important
You should derive custom exceptions from the Exception class rather
than the ApplicationException class. You should not throw an
ApplicationException exception in your code, and you should not catch
an ApplicationException exception unless you intend to re-throw the
original exception.
So for custom exception we should use Exception as a base class
Fundamentally, it doesn't matter. If your exception type would be a better logical fit when derived from one of the system-provided exceptions, as a user I'd prefer that kind of implementation. Think about what happens when user of your code catches the exceptions, and plan accordingly.

Reason of not marking Exception as abstract

Microsoft's Best Practice says:
Introduce a new exception class only when a predefined one doesn't apply.
And:
When a custom exception is necessary, name it appropriately and derive it from the Exception class.
Deriving from the Exception class makes sense because that makes it possible for us to handle specific exceptions and (for example) log and throw the rest:
try
{
//something that might throw exceptions
}
catch(InvalidOperationException)
{
//Do something
}
catch(Exception ex)
{
//Log and throw other exception
throw;
}
I cant think of a reason why one would want to create an instances of the Exception base class. So why is Exception not marked as an abstract class?
I thought catching an abstract Exception might cause some special behaviour, but that does not seem to be the case:
public abstract class AbstractException : Exception
{
}
public class MyException : AbstractException
{
}
//...
try
{
throw new MyException();
}
catch (AbstractException)
{
//Works fine
}
Abstract classes are only required when there are abstract members. Exception doesn't have those so it doesn't require to be abstract.
But Microsoft could make it abstract to comply to their own best practices. Well, best practices are not set in stone, so a developer should have the choice to deviate from them. The non-abstract Exception provides that possibility.
There are lot of cases when you don't need any special or additional information to "describe" an exceptional situation in a computation flow. The Exception type is very suitable for such situations so that you don't have to define a new types for the generic exceptional situations. Being an abstract type the Exception wouldn't allow you to instantiate it and you'll have to invent some generic exception types from project to project in order to have an exception type "understandable" by all high-level consumers (that is provide a way to all consumers to catch and handle all exceptions regardless of an exception type specialization).

Exception Driven Programming C#

Although not much popular in Micro-services & Restful architecture, (I'm presuming). We prefer to raise graceful business excetion by means of custom exception classes derived from ApplicationException.
Is there any mechanism to self declare, by some compile feature that
Ex1, Ex2, Ex3 are the possible business exceptions thrown by a class service.
If you're already familiar with WCF, hope you have got it. I'm Something on the lines of WCF
(Exception contract)
Example:
public class BlobChecksumMatchException : ApplicationException
{
public BlobChecksumMatchException(string msg) : base(msg)
{
}
}
EDIT:
(Not to mention Exception base of course can be thrown for whatsoever reason, I'm just looking out for predefining business exception classes)
There's no such built-in mechanism in C# or .NET. However, you have a couple of workaround options:
1) If that information is for human consumption, you can use XML documentation comments as pointed out by Andreas Zita.
2) If you need a machine-readable mechanism, you could declare a custom "ThrowsException" attribute and apply it to your class or methods, then retrieve these using reflection:
class MyBusinessClass
{
[ThrowsException(typeof(Ex1))]
[ThrowsException(typeof(Ex2))]
public void DoSomething() {}
}
Note however that reflection is expensive, depending on your performance requirements you might need to implement some caching mechanism for that information.

Custom Exceptions and reducing duplicated code

I have decided to use Exceptions in my code to pass error handling around. I found myself duplicating code each time I wanted to create a new exception. These classes were nothing special and only contained a messaged. But I have come to rely on type safety when handing them. Is there a way to provide a new exception class type without having to re-implement the constructors?
[Serializable]
class MyNewException : MyBaseException
{
public MyNewException (String tMsg)
: base(tMsg)
{
}
public MyNewException (String tMsg, Exception tInnerEx)
: base(tMsg, tInnerEx)
{
}
}
The code above is duplicated many times over for each different type of exception I want to define.
Unfortunately, no, the constructors have to be provided since they are not inherited.
In addition, unless you are catching these specific exceptions and performing explicit processing when they occur, I would recommend having a generic exception that contains the additional information that you might need. However, this may not apply in your case.

Are there standard naming conventions for this example of The Template Method Pattern?

I want to create an abstract class with an common exception handling pattern:
public abstract class Widget
{
public IFoo CreateFoo()
{
try
{
CreateFooUnsafe();
}
catch(Exception ex)
{
throw new WidgetException(ex, moreData, evenMoar);
}
}
protected abstract IFoo CreateFooUnsafe();
}
The intention is to have a standard exception handling pattern across all deriving objects. The abstract CreateFooUnsafe() method should not be expected to contain any exception handling. Implementations would probably a single line of return new Foo(...)
What I want to know is whether there are any standard naming conventions associated with this pattern, particularly where exception-throwing code is expected?
The names above seem somewhat appropriate, but not entirely without smell.
This appears to be an example of the template method pattern.
Template method is a pattern which can be expressed in many object-oriented languages by using a public non-virtual function to implement some over-arching behavior, and a protected virtual (or abstract) method to supple the concrete behavior in subclasses.
In your example, you are using the template method to catch all exceptions bubbling out of the inner implementation and wrapping them in a custom exception type. One comment I would make about this specific practice, is that it only makes sense if you can add contextual information that would allow calling code to better handle the exception. Otherwise, it may be better to simply allow the source exceptions to propogate out.
The short answer is no.
There is no convention in the Template Pattern to designate what type and when an exception is thrown. That kind of information is included in some section of the documentation as per MSDN. Using C# and XML comments you can easily generate such documentation.
I'm under the impression that there might be a naming convention in place for the Template Pattern itself sans any referencing to exception handling. As I understand it, naming might look like this:
public abstract class Widget
{
public void PerformAction()
{
this.PerformActionImpl();
}
protected virtual void PerformActionImpl(){}
}
Where Impl is a shorthand for "Implementation". Personally I don't like that naming style so don't use it but I'm sure I've read it somewhere semi authoritative that that is "the" way to do it.
I wouldn't use any of this in your case however as what you really to seem to want to either Factory or AbstractFactory.
..
With regard to your exception query, it seems to me the code is a little inside out tho I disagree with some of the other comments depending on your circumstances.
Wrap and throw is an entirely valid exception handling technique.
The additional context provided by the type of the exception itself may well be enough to route the exception to an appropriate handler. i.e. you've transformed an Exception into a WidgetException which one would expect then has context within your application. So that might well be good enough.
Where you've done the wrapping I do however disagree with.
I would do the catching wrapping and throwing from within the subclass implementation of the virtual method as only that subclass is going to have enough understanding of what it's doing to know whether the Exception is indeed a WidgetException and therefore wrap and throw or something a little more hairy that should propagate.
The code as it stands is making some massive assumptions about the cause of the exception and in that sense rendering any use of a custom exception next to useless. i.e. everything is now a WidgetException.
So while I believe type alone could be enough to contextualise the exception I dont believe the code is making that decision in the right place. I understand the motivation behind the implementation you've chosen as it seems like a really tasty shortcut, "the myth of the all knowing base class" but the mere fact that you declared it as abstract should provide a significant clue that the class is intended to be ignorant by design.
So with respect to the crosscutting concern of exception handling I don't think you should looking so much for a pattern to make your life easier but rather a framework to abstract all the guff away.
For example the Enterprise Library.
There are several different patterns swimming about in the code above. Among other things, it looks a bit like the Abstract Factory pattern, i.e., you've got an abstract class which is implementing a factory method that returns concrete objects which implement a specific interface.
As to whether this sort of exception handling is a good idea or not -- I would tend to agree with the other folks, that I can't typically see a lot of value in this approach. I see what you're trying to do, namely, provide a single sort of exception to handle, much as the CreateFoo() returns a single interface (IFoo). But the only benefit I can think of to that approach is if you provide some interesting and relevant troubleshooting information in the WidgetException (e.g., some database or service connection strings, or some special processing logic around the stack trace). If you're just wrapping the original exception so that your clients can deal with a WidgetException, you haven't really accomplished much: they could just as easily deal with the base Exception type.

Categories

Resources