When should I create my own custom exception class rather than using a one provided by .Net?
Which base exception class should I derive from and why?
Why create your own exception?
You create your own exception so that when you throw them, you can have specific catches and hence differentiate them from system thrown (unhandled) exceptions.
What class should you derive it from?
Earlier, it was standard practice for custom exceptions to be derived from ApplicationException class but over time, MS recommendations have changed encouraging developers to derive from System.Exception itself rather than ApplicationException
This may seem a bit obvious but you should create an exception when no built in exceptions make sense. Typically I will define a base exception for a library I am working on.
public class MyLibraryException : Exception
{
// .....
}
Then I will create an exception for situations that may arise when using the library.
public class SomethingHorribleException : MyLibraryException
{
// .....
}
Then the client can always know that my library will throw something that inherits MyLibraryException.
The goal of exception handling should be to create a clear understanding of what went wrong. Therefore, you should define your own exception any time the provided exceptions do not provide that clear understanding.
For example, I'm writing an application which converts Arabic Numerals to Roman Numerals. One of the constraints in this application is that Roman Numerals must fall within the range 0 < x < 4000.
private string ToRoman(int number)
{
if (number > 0 && number < 4000)
{
//ConvertHere
}
else
{
//Custom exception used for readability purposes.
throw new NumeralOutOfRangeException();
}
}
As for which base class to use, Microsoft recommends that user defined exceptions subclass Exception. (http://msdn.microsoft.com/en-us/library/seyhszts.aspx)
One reason to create your own exception is to be able to isolate them for catching. For example:
try {
// do stuff
} catch (MyCustomException e) {
// handle this known exception
}
All other exceptions can bubble up and be handled at another level.
The answers so far all look good, but I would also add:
To hide implementation details that might otherwise be exposed because you need to handle those exceptions.
E.g. You don't want your UI to catch SQLException. You should throw your own exceptions out of your data access code and let your UI deal with those. If you changed to a non database provider for data storage (e.g. XML, file system, etc), you would not need to change your UI code.
However, I would only do that if I was handling them in my UI code explicitly.
I'd create my own excpetion class if i wanted to add other properties to it such as variables, location, user name, num returned records etc.
essentially i'd create a class that would narrow down what the error was and how to re-create it.
edit
oh and you could add validation errors to an exception class that can be passed to the front end to show the errors.
Related
I've read many sites and other responses on StackOverflow, but I still haven't grasped the the importance of exception handling and why we "throw" them.
For this post, my understanding of an exception can best be described as:
"An exception is a problem that arises during the execution of a program. A C# exception is a response to an exceptional circumstance that arises while a program is running..." https://www.tutorialspoint.com/csharp/csharp_exception_handling.htm
When handling exceptions, I often see the following code snipets:
try
{
// Do something that causes an Exception
}
catch (Exception)
{
// Could have error logging here
throw;
}
If you do not perform any error logging, why have the "try/catch" and "throw" statement? The code will still throw an exception regardless of whether I try/catch. I must be missing something. What does "throwing" do?
I've included a basic divide by zero scenario in the following:
https://repl.it/BjgV/24. When you remove the "try/catch/throw" you see the same results.
Something to keep in mind is not only that caught exceptions can be used for logging errors, they can be used for handling errors that might arise.
Let's say you have some kind of Widget object, that has properties you initialize via arguments to a constructor:
public class Widget
{
public string Name;
Widget(string widgetName)
{
if (widgetName != "")
Name = widgetName;
else
throw new ArgumentException("Name must be provided for widget.");
}
}
In this case, we have a situation where we want to require our Widget have a name when it's instantiated - we check the argument to see if it's blank, and we throw an ArgumentException to indicate that something is wrong with one of the arguments to the constructor, as well as include a helpful message about what specifically went wrong.
This means we can then have context-specific validation logic in a wrapper, rather than having to have everything crammed into our base Widget class:
public Widget ForCaseA (string widgetName)
{
Widget w;
try {
w = new Widget(widgetname);
}
catch (ArgumentException as argEx) // We're specifically catching the subtype of ArgumentExceptions; generic Exceptions or other types of exception wouldn't be caught here and would bubble up out of this try/catch block.
{
// At this point, we could look at the specific data in the exception object to determine what needs to happen to resolve the exception. Since there's only one argument and it's throwing an ArgumentException, we know it's going to be a problem with a bad widgetName. In this case, we can say 'well, in this specific case, we want to give it a default widget name'.
w = new Widget("DefaultName");
}
return w;
}
One of the ways catching exceptions by type becomes exceptionally useful is when you use inheritance to create your own types based off the generic Exception class; e.g. giving your Widgets a WidgetException. This lets you catch issues specific to your class/entity (like the widget's name), but doesn't have to handle issues that fall outside the scope of the Widget itself.
"Throwing" is sometimes (in non-oop languages) the same as "raising" an error.
If we catch an exception, we might want to bubble that up to some method higher in the callstack, and perhaps generalize it more in the process. Thus, we might use something like:
try { doSomething(); }
catch (VerySpecificException ex) {
throw new SomeGenericException(ex);
}
This allows us to expect only generic exceptions in the higher-level programming, while maintaining a full stack trace and inner exceptions so we can see where it came from.
Throw, on it's own (such as in your example), simply pushes the error up to the next caller, with no changes. In your exact example, you might just leave out the try/catch altogether, as the result will be the same (the exception gets pushed to the next block: excepting maybe if you have some AOP or weaving in there to handle it, but that's a bit beyond this answer I think).
If there's no try/catch block, the exception is pushed back up to the next method in the callstack. If there's no try/catch blocks anywhere, the exception is said to be "unhandled", and your application crashes. There's no excuse for an unhandled exception to make it to the top.
Specifically regarding this part:
If you do not perform any error logging, why have the "try/catch" and "throw" statement?
Aside from logging the exception, in some situations you may want to:
Wrap the exception in a meaningful user-defined exception which you throw to raise some error.
Release certain resources just in case the exception happens and bubble it up for potential handling somewhere else.
These are just two examples.
Should I catch exceptions in my method for "purely documenting" purposes, thus encapsulating the error-documentation inside the method itself, or is that responsibility of the caller?
Suppose I call numerous other methods in my EncryptPackage() method, including the framework ones, which potentially throw numerous exceptions. I wrap everything in using blocks, so no need to catch exceptions for cleanup (or I use try/finally for cleanup). Should I catch the exception anyway, and provide the details about the context of that method, or is it the responsibility of caller method?
Here is the case one:
[Serializable]
class TestClassException : Exception
{
public TestClassException() : base() { }
public TestClassException(string message) : base(message) { }
public TestClassException(string message, Exception innerException) : base(message, innerException) { }
}
class TestClass
{
public TestClass() { }
public void EncryptPackage()
{
try
{
DoSomething();
DoAnotherThing();
}
catch (Exception ex)
{
throw new TestClassException("Error occurred during package encryption", ex);
}
}
}
class ConsumerExample
{
public ConsumerExample() { }
public void DoSomeStuff()
{
TestClass testClass = new TestClass();
try
{
testClass.EncryptPackage();
}
catch (TestClassException ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString());
}
}
}
In this code, notice how the EncryptPackage() method catches all possible exceptions, just to "decorate the error text", with a "Error occurred during package encryption" text. EncryptPackage() here encapsulates the error-description logic.
And here is another technique:
class TestClass2
{
public TestClass2() { }
public void EncryptPackage()
{
DoSomething();
DoAnotherThing();
}
}
class ConsumerExample2
{
public ConsumerExample2() { }
public void DoSomeStuff()
{
TestClass testClass = new TestClass();
try
{
testClass.EncryptPackage();
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show("Error occurred during package encryption.\r\n\r\n" + ex.ToString());
}
}
}
In this example, EncryptPackage() does not catch anything, because the caller documents the error case anyway with "Error occurred during package encryption.\r\n\r\n" message.
Please note that this is a very simplified example, in real world there will be numerous hierarchical classes, and exceptions will be propagating through the long call stack, so which method of catching exceptions is preferred? Second approach seems "cleaner", because the exception is handled in a layer where some "actual handling" (e.g. displaying to user) is going to take place. Call stack information would be preserved in exception object, so technically it will be possible to find out where exactly the exception was thrown. But... that does not seem as "well-documenting" as the first approach, where each level of abstraction adds its own description to the error, preserving the previous exception in an innerException member. In this case, when the execution leaves the TestClass layer, it already contains detailed description of the error that happened within this class. So this feels to be the better encapsulation of error-handling logic.
Which one to use?
There is a chapter on this in Effective Java:
Higher layers should catch lower-level exceptions and, in their place,
throw exceptions that can be explained in terms of the higher-level
abstraction. This idiom is known as exception translation.
I prefer your second example, mainly because it can signicantly reduce the amount of error handling code you have to write, especially if you are writing custom exceptions - with the first example you could end up with a lot of custom exception classes which do not give much benefit (you already have the call stack to tell you where the exception came from).
You might think it is nice to have a more descriptive error message, but who benefits from this? The end-user? Should you even be displaying exception messages to your user (and what language are you going to use)? A lot of the time the user just needs to know that there has been an internal error, and they should give up (restart), or try again. Do you the developer benefit? You are probably going to end up examining the call stack anyway with the source code in front of you, so you don't really need a more descriptive message, you can see for yourself what the code is doing at that point.
This is not a hard and fast rule. Most of the time I only catch exceptions at the top level, where I log them and report an error to the user. If you are reporting the exception directly to the user, then often the original exception does not benefit from translation, e.g., if you try to open a non-existent file, then the System.IO.FileNotFoundException is descriptive enough so why translate it to something else? Do you really want to make the same judgement call ("I know better than the library author so I am going to translate their carefully crafted exceptions") for all of the gazillions of exceptions out there? I only catch exceptions lower down if I want to recover from them (generally not possible), or, very rarely, I want to translate them to a more descriptive exception.
In a layered architecture, it can make sense to translate exceptions between the layers, e.g., catch exceptions coming out of the data access layer to a form suitable for the application layer, and similarly between the application layer and the user interface, but I don't know if you are working on that type of system.
If you want to document your exceptions, you should use the exception tag in the xml documentation for the method. This can then be used to general help files from the documentation, e.g., using SandCastle.
As per #Sjoerd above, translate exceptions so they are in the same level of abstraction. In your case EncryptPackage should translate any lower-level exceptions itself, NOT the caller.
Say the lower-level exceptions were from a DB layer (say DBException). Would the caller expect to understand DBException? The answer is NO: the caller wants to encrpt a package, not a DBException. The lower-level exceptions should be chained INSIDE the higher-level exception for debugging purposes.
Finally, I know TestClassException is an example, but make sure the exception class describes the problem clearly: I, personally, don't like bland, generic exception classes (except to make a common base-class for other exceptions).
You should try/catch in few, easily distinguished situations:
any method that can be invoked "externally", such as your app's entry point, UI events, multi-threaded calls and others. Put some log output or message on each and every catch you have. This will prevent your app from crashing (for the most part) as well as provide you or the user with some feedback on how to fix the problem.
when you can really handle the exception. This means your app can, for example, opt for a secondary database or server URL, apply a different processing etc.
when you want to prevent something optional from ruining the main workflow, for example failing to delete your temp file shouldn't cause your process to fail.
there are probably some other places where you'll need a try/catch but these should be rare
Always combine error handling with a decent way of logging and/or messaging the user, don't let any exceptions info disappear because that's how you get apps and don't behave well for "no apparent reason" - at least the reason should be made apparent.
Also - don't use exceptions to control your workflow. There really shouldn't be any "throw"s unless there's absolutely no other way of doing something.
What are the pros and cons of implementing a custom exception as follows:
Create an enum which represents error messages in its descriptions:
public class Enums
{
public enum Errors
{
[Description("This is a test exception")]
TestError,
...
}
}
Create a custom exception class:
public class CustomException : ApplicationException
{
protected Enums.Errors _customError;
public CustomException(Enums.Errors customError)
{
this._customError = customError;
}
public override string Message
{
get
{
return this._customError!= Enums.Errors.Base ? this.customError.GetDescription() : base.Message;
}
}
}
The GetDescription method is an enum extension method which gets the enum description using reflection. This way, I can throw exception like:
throw new customException(enums.Errors.TestError);
And show it to the user in catch block like:
Console.WriteLn(ex.Message);
I've seen this approach recommended by an MVP. What are the benefits of this approach over the followings:
Using generic exception: throw new Exception("Error Message");.
Using Custom Exception: Define custom exceptions for any situation. e.g. (WebServiceException class, AuthenticationException class, etc.)
Here's the link to the recommendation by the MVP.
Thank you.
Personally, i don't think it's a good idea.
You should always throw as specific exceptions as possible. The same goes for catching.
It's easy to decide if we want to catch a WebServiceException or AuthenticationException, but with your Enum-example, we have to parse a string to decide if we want to catch it or not. What happens if this message changes?
I don't think it has any benefits at all. For each error type, you have to create a new Enum member. Why not create a new class instead?
The major advantage of custom exceptions is the language support for differentiation between different exception types. For example
try
{
SomeFunc()
}
catch( CustomException EX)
{
//This is my error that I know how to fix
FixThis()
DoSomeAwesomeStuff()
}
catch( Exception exa)
{
//Somthing else is wrong
WeepLikeBaby();
}
If I use the message Property
try
{
SomeFunc()
}
catch( Exception exa)
{
if(exa.Message == "ErrType 1")
{
DoStuff;
}
if(exa.Message == "ErrType 2")
{
Die();
}
}
Utilizing The Base enum example can still retain this capability. However you give yourself one place to define your messages, but that is solved in a variety of different ways by applications. The enum example would make creating localized messages pretty simple as It will give you A way to define your message strings independently.
Another Advantage is that you can add Cusotm data that makes sense in you application. Say for example you have a customer information system, and the customer ID is almost always going to be important. If you utilize the message property only, every handler will have to know how to parse out that information if needed.
public class MyCustomeEx : Exception
{
int CustID { get; set; }
}
public void Fail()
{
//Awww Customer error
throw new MyCustomeEx () {CustID = 123}
}
Option 1 I would not recommend. You should not be throwing System.Exception at all. You should always throw the most specific exception available for your situation in order to have reasonably structured exception handling in your code.
The major drawback I see in your proposed method (Errors enum) is that there is no way you can decide if you want to handle or not the exception without catching it first. With custom exceptions you can make that decision beforehand.
Please see my (accepted) answer at the following similar Stack Overflow question: Custom exception vs built in exception with very descriptive message. It should prove helpful in providing arguments against frivilous custom exceptions.
The link to the MVP's recommendation was shared in comments.
After looking at the code and the question I think the reason for this is to limit the possible messages in the exception. And maybe help with localizing exception texts, but then there's extra work to do in this example. Anyways, such a method shouldn't be used for creating "Exception sub-types" that are processed differently.
I'm writing a c# application which uses automation to control another program. Naturally that program must be running for my program to work. When my program looks for the application and can't find it I'd like to throw an exception (for now later of course I could try opening the application, or telling the user to open it, or ...).
Should I implement a custom exception - or use the existing NotSupportedException (or one of the other .NET exceptions). If a custom exception, what would you suggest? I was thinking of implementing a custom exception I'd call it MyAppNameException and then just use the message to declare what the problem was?
Are there any general rules to throwing exceptions in a way that makes your program more readable and user friendly, or am I just giving this too much thought :)?
Thanks!
First, define MyAppCustomException as an abstract base class.
Then inherit from it with AppNotFoundCustomException.
This way you can catch all exceptions from your app, or just specific ones.
Here's some example code that illustrates the concept:
public abstract class MyAppCustomException : System.Exception
{
internal MyAppCustomException(string message)
: base(message)
{
}
internal MyAppCustomException(string message, System.Exception innerException)
: base(message,innerException)
{
}
}
public class AppNotFoundCustomException : MyAppCustomException
{
public AppNotFoundCustomException(): base("Could not find app")
{
}
}
And here's a client try/catch example:
try
{
// Do Stuff
}
catch(AppNotFoundCustomException)
{
// We know how to handle this
}
catch(MyAppCustomException) // base class
{
// we don't know how to handle this, but we know it's a problem with our app
}
The Framework Guidelines book that I use indicates that you should only create a custom exception when the error condition can be programmatically handled in a different way than any existing exceptions.
In your case, if you wanted to create a custom exception in order to launch a back-end installation program, that is unique and I think a custom exception would be okay.
Otherwise, something from the System.Runtime.InteropServices.ExternalException heirarchy may be appropriate.
Yeah, you're overdoing it. Nothing good is going to happen when you throw an exception, any exception, that program isn't magically going to start running when you do. Only bad things might happen, like some code actually catching that exception and trying to continue. Or nobody catching it and getting a Windows Error Report dialog. Might as well put up a message box and call it a day with Environment.Exit().
Of course, it could be more useful to the user if you actually start that program if you find it isn't running.
You certainly shouldn't use NotSupportedException, as you suggest, because your application does support the method in question. NotSupportedException is used when a interface or abstract class is implemented, but with some members not fully implemented as they don't make sense in the context (reading from an output stream, clearing a readonly collection, etc).
A closer match is something InvalidOperationException, where a member can be used, but not given the current state.
You say "application", which suggests an executable rather than a component for use by something else. In this case you aren't going to bubble the exception up to the calling code (since there isn't calling code) but either raise a dialog (for a GUI app) or write to Console.Error (for a console app). This makes it likely that either you're just going to display the value of the Message property of the exception, or that you just need the class type to flag a particular message. Either simply deriving AppNotRunningException from Exception or just using Exception directly will probably serve perfectly well, depending on which of the two you find most convenient.
Once I read an MSDN article that encouraged the following programming paradigm (its not 100% true... see edit):
public class MyClass
{
public void Method1()
{
NewCustomException();
}
public void Method2()
{
NewCustomException();
}
void NewCustomException()
{
throw new CustomException("Exception message");
}
}
Do you think this paradigm makes sense? Wouldn't it be enough to store the exception message in a static const field and then pass it to the exception's constructor, instead of encapsulating the whole exception throw?
EDIT:
Use exception builder methods. It is
common for a class to throw the same
exception from different places in its
implementation. To avoid excessive
code, use helper methods that create
the exception and return it.
I just noticed (see citation), that the article tells to return an exception:
public class MyClass
{
public void Method1()
{
throw NewCustomException();
}
public void Method2()
{
throw NewCustomException();
}
CustomException NewCustomException()
{
return new CustomException("Exception message");
}
}
What do you think about this?
My understanding is that passing an exception instance around is a faux pas if for no other reason than you lose the stack trace associated with the exception. Calling another method would change the stack trace and thereby make it effectively useless. I'd recommend at a minimum getting the stack trace off the exception and passing it as an argument to some helper if that's the road you're going to go down.
That's a refactor too far in my book. You have to go back up a line in the stack trace to see exactly where the problem occured. If your custom exception is always using the same message, put it in the CustomException class. If it's only the same within the code you've quoted, then yes, put it in a const field (you can't have static const - it's implicitly static).
Another problem you get doing that is that there will be lots of places where you wont even be able to throw an exception because the compiler wont allow it. Consider these two methods added to your class:
public string GetFoo1(bool bar)
{
if (bar)
return "";
else
NewCustomException();
}
public string GetFoo2(bool bar)
{
if (bar)
return "";
else
throw new CustomException("Exception message");
}
GetFoo1 will not compile while GetFoo2 will.
I would have a method that builds an Exception, rather than one that throws it. As in the sample below. I seem to remember seeing a Microsoft guideline that recommended this, but I can't remember where.
With this technique, if you want to change the exception type for any reason, you only need to do so in one place (e.g. a change from ConfigurationException to ConfigurationErrorsException when upgrading from .NET 1.x to .NET 2.0).
Also you respect the DRY principle by having a single copy of the code that builds the exception with its message and any other data included in the exception.
You obviously wouldn't do this in trivial cases (e.g. you wouldn't replace throw new ArgumentNullException("myParamName") by throw BuildArgumentNullException("myParamName"))
private static Exception BuildSomeException(... parameters with info to include in the exception ...)
{
string message = String.Format(...);
return new SomeException(message, ...);
}
...
throw BuildSomeException(...);
I don't see the point of making a method that simply throws an exception. But, I do think trowing custom exceptions has value. If all of the exceptions you throw are children of a custom exception, it allows you to quickly see if the thrown exception is one you are accounting for or something you have not handled yet. Also, you can then catch MyBaseException and it is not as bad as catching Exception.
It is handy to do this if you don't know how you plan to handle exceptions, exactly. Do you want to just throw it? Or perhaps later you are going to log the exception somewhere then throw it? Or maybe pass some arguments (i.e. method name, etc.) that get bundled in with the exception?
In this case, creating a separate method that handles the exception situation is convenient when you want to change it.
I don't usually bother with this - instead, just figure out upfront how you are going to handle exceptions (i.e. what string information you are going to putin the message).
I generally prefer to store exception messages as resources. That serves several purposes:
If the requirement comes down to localize exception messages, it's a no-brainer.
Exception messages tend to be more standardized across developers since it's extra work to create a new, but only slightly different message.
If you ensure that messages are referenced by an identifier, and include the identifier with the exception when it's thrown, then tracing a message to the code that threw it is easier.
Downside is it does require (just) slightly more effort up front than hard-coding the messages.