I have read a few of the other questions regarding C# Exception Handling Practices but none seem to ask what I am looking for.
If I implement my own custom Exception for a particular class or set of classes. Should all errors that relate to those classes be encapsulated into my exception using inner exception or should I let them fall through?
I was thinking it would be better to catch all exceptions so that the exception can be immediately recognized from my source. I am still passing the original exception as an inner exception. On the other hand, I was thinking it would be redundant to rethrow the exception.
Exception:
class FooException : Exception
{
//...
}
Option 1: Foo encasulates all Exceptions:
class Foo
{
DoSomething(int param)
{
try
{
if (/*Something Bad*/)
{
//violates business logic etc...
throw new FooException("Reason...");
}
//...
//something that might throw an exception
}
catch (FooException ex)
{
throw;
}
catch (Exception ex)
{
throw new FooException("Inner Exception", ex);
}
}
}
Option 2: Foo throws specific FooExceptions but allows other Exceptions to fall through:
class Foo
{
DoSomething(int param)
{
if (/*Something Bad*/)
{
//violates business logic etc...
throw new FooException("Reason...");
}
//...
//something that might throw an exception and not caught
}
}
Based on my experience with libraries, you should wrap everything (that you can anticipate) in a FooException for a few reasons:
People know it came from your classes, or at least, their usage of them. If they see FileNotFoundException they may be looking all over for it. You're helping them narrow it down. (I realize now that the stack trace serves this purpose, so maybe you can ignore this point.)
You can provide more context. Wrapping an FNF with your own exception, you can say "I was trying to load this file for this purpose, and couldn't find it. This hints at possible correct solutions.
Your library can handle cleanup correctly. If you let the exception bubble, you're forcing the user to clean up. If you've correctly encapsulated what you were doing, then they have no clue how to handle the situation!
Remember to only wrap the exceptions you can anticipate, like FileNotFound. Don't just wrap Exception and hope for the best.
Have a look at this MSDN-best-practises.
Consider to use throw instead of throw ex if you want to re-throw caught exceptions, because on this way the original stacktrace keeps preserved(line numbers etc.).
I always add a couple of properties when creating a custom exception. One is user name or ID. I add a DisplayMessage property to carry text to be displayed to the user. Then, I use the Message property to convey technical details to be recorded in the log.
I catch every error in the Data Access Layer at a level where I can still capture the name of the stored procedure and the values of the parameters passed. Or the inline SQL. Maybe the database name or partial connection string (no credentials, please). Those may go in Message or in their own new custom DatabaseInfo property.
For web pages, I use the same custom exception. I'll put in the Message property the form information -- what the user had entered into every data entry control on the web page, the ID of the item being edited (customer, product, employee, whatever), and the action the user was taking when the exception occurred.
So, my strategy as per your question is: only catch when I can do something about the exception. And quite often, all I can do is log the details. So, I only catch at the point where those details are available, and then rethrow to let the exception bubble up to the UI. And I retain the original exception in my custom exception.
The purpose of custom exceptions is to provide detailed, contextual information to the stacktrace to aid in debugging. Option 1 is better because without it, you don't get the "origin" of the exception if it occurred "lower" in the stack.
if you run the code snippet for 'Exception' in Visual Studio you have a template of a good practice exception writing.
Note
Option 1: your throw new FooException("Reason..."); won't be caught as it's outside try / catch block
You should be only catching exceptions that you want to process.
If you're not adding any additional data to the exception than use throw; as it won't kill your stack. In Option 2 you still might do some processing inside catch and just call throw; to rethrow original exception with original stack.
The most important thing for code to know when catching an exception, which is unfortunately completely missing from the Exception object, is the state of the system relative to what it "should" be (presumably the exception was thrown because there was something wrong). If an error occurs in a LoadDocument method, presumably the document didn't load successfully, but there are at least two possible system states:
The system state may be as though the load were never attempted. In this case, it would be entirely proper for the application to continue if it can do so without the loaded document.
The system state may be sufficiently corrupted that the best course of action would be to save what can be saved to 'recovery' files (avoid replace the user's good files with possibly-corrupt data) and shut down.
Obviously there will often be other possible states between those extremes. I would suggest that one should endeavor to have a custom exception which explicitly indicates that state #1 exists, and possibly one for #2 if foreseeable but unavoidable circumstances may cause it. Any exceptions which occur and will result in state #1 should be wrapped in an exception object indicating state #1. If exceptions can occur in such a fashion that the system state might be compromised, they should either be wrapped as #2 or allowed to percolate.
Option 2 is best. I believe best practice is to only catch exceptions when you plan to do something with the exception.
In this case, Option 1 just is wrapping an exception with your own exception. It adds no value and users of your class can no longer just catch ArgumentException, for example, they also need to catch your FooException then do parsing on the inner exception. If the inner exception is not an exception they are able to do something useful with they will need to rethrow.
Related
Can following code be considered as a good practice? If not, why?
try
{
// code that can cause various exceptions...
}
catch (Exception e)
{
throw new MyCustomException("Custom error message", e);
}
Short answer: Don't do this unless there is some reason that you must. Instead, catch specific exceptions you can deal with at the point you can deal with them, and allow all other exceptions to bubble up the stack.
TL;DR answer: It depends what you're writing, what is going to be calling your code, and why you feel that you need to introduce a custom exception type.
The most important question to ask, I think, is if I catch, what benefit does my caller get?
Do not hide information that your caller needs
Do not require your caller to jump through any more hoops than necessary
Imagine you're processing a low-level data source; maybe you're doing some encoding or deserialisation. Our system is nice and modular, so you don't have much information about what your low-level data source is, or how your code is being called. Maybe your library is deployed on a server listening to a message queue and writing data to disk. Maybe it's on a desktop and the data is coming from the network and being displayed on a screen.
There are lots of varied exceptions that might occur (DbException, IOException, RemoteException, etc), and you have no useful means of handling them.
In this situation, in C#, the generally accepted thing to do is let the exception bubble up. Your caller knows what to do: the desktop client can alert the user to check their network connection, the service can write to a log and allow new messages to queue up.
If you wrap the exception in your own MyAwesomeLibraryException, you've made your caller's job harder. Your caller now needs to:-
Read and understand your documentation
Introduce a dependency on your assembly at the point they want to catch
Write extra code to interrogate your custom exception
Rethrow exceptions they don't care about.
Make sure that extra effort is worth their time. Don't do it for no reason!
If the main justification for your custom exception type is so that you can provide a user with friendly error messages, you should be wary of being overly-nonspecific in the exceptions you catch. I've lost count of the number of times - both as a user and as an engineer - that an overzealous catch statement has hidden the true cause of an issue:-
try
{
GetDataFromNetwork("htt[://www.foo.com"); // FormatException?
GetDataFromNetwork(uriArray[0]); // ArrayIndexOutOfBounds?
GetDataFromNetwork(null); // ArgumentNull?
}
catch(Exception e)
{
throw new WeClearlyKnowBetterException(
"Hey, there's something wrong with your network!", e);
}
or, another example:-
try
{
ImportDataFromDisk("C:\ThisFileDoesNotExist.bar"); // FileNotFound?
ImportDataFromDisk("C:\BobsPrivateFiles\Foo.bar"); // UnauthorizedAccess?
ImportDataFromDisk("C:\NotInYourFormat.baz"); // InvalidOperation?
ImportDataFromDisk("C:\EncryptedWithWrongKey.bar"); // CryptographicException?
}
catch(Exception e)
{
throw new NotHelpfulException(
"Couldn't load data!", e); // So how do I *fix* it?
}
Now our caller has to unwrap our custom exception in order to tell the user what's actually gone wrong. In these cases, we've asked our caller to do extra work for no benefit. It is not intrinsically a good idea to introduce a custom exception type wrapping all exceptions. In general, I:-
Catch the most specific exception I can
At the point I can do something about it
Otherwise, I just let the exception bubble up
Bear in mind that hiding the details of what went wrong isn't often useful
That doesn't mean you should never do this!
Sometimes Exception is the most specific exception you can catch because you want to handle all exceptions in the same way - e.g. Log(e); Environment.FailFast();
Sometimes you have the context to handle an exception right at the point where it gets thrown - e.g. you just tried to connect to a network resource and you want to retry
Sometimes the nature of your caller means that you cannot allow an exception to bubble up - e.g. you're writing logging code and you don't want a logging failure to "replace" the original exception that you're trying to log!
Sometimes there's useful extra information you can give your caller at the point an exception is thrown that won't be available higher up the call stack - e.g. in my second example above we could catch (InvalidOperationException e) and include the path of the file we were working with.
Occasionally what went wrong isn't as important as where it went wrong. It might be useful to distinguish a FooModuleException from a BarModuleException irrespective of what the actual problem is - e.g. if there's some async going on that might otherwise prevent you usefully interrogating a stack trace.
Although this is a C# question, it's worth noting that in some other languages (particularly Java) you might be forced to wrap because checked exceptions form part of a method's contract - e.g. if you're implementing an interface, and the interface doesn't specify that the method can throw IOException.
This is all pretty general stuff, though. More specifically to your situation: why do you feel you need the custom exception type? If we know that, we can maybe give you some better tailored advice.
There's an excellent blog post by Eric Lippert, "Vexing exceptions". Eric answers your question with some universal guidelines. Here is a quote from the "sum up" part:
Don’t catch fatal exceptions; nothing you can do about them anyway, and trying to generally makes it worse.
Fix your code so that it never triggers a boneheaded exception – an "index out of range" exception should never happen in production code.
Avoid vexing exceptions whenever possible by calling the “Try” versions of those vexing methods that throw in non-exceptional
circumstances. If you cannot avoid calling a vexing method, catch its
vexing exceptions.
Always handle exceptions that indicate unexpected exogenous conditions; generally it is not worthwhile or practical to anticipate
every possible failure. Just try the operation and be prepared to
handle the exception.
No, generally, you should not do that: this may mask the real exception, which may indicate programming issues in your code. For example, if the code inside the try / catch has a bad line that causes an array index out of bound error, your code would catch that, too, and throw a custom exception for it. The custom exception is now meaningless, because it reports a coding issue, so nobody catching it outside your code would be able to do anything meaningful with it.
On the other hand, if the code inside the try / catch throws exceptions that you expect, catching and wrapping them in a custom exception is a good idea. For example, if your code reads from some special file private to your component, and the read causes an I/O exception, catching that exception and reporting a custom one is a good idea, because it helps you hide the file operation from the caller.
It's completely OK. You don't have to catch each exception type separately. You can catch specific type of exception, if you want to handle it in specific way. If you want to handle all exceptions in same way - catch base Exception and handle it as you do. Otherwise you will have duplicated code in each catch block.
This is what I usually say about exception handling:
The first thing to do with exceptions is ... nothing. There will be a high level catch all handler (like the yellow ASP.NET error page) that will help you, and you will have a full stack frame (note this is not the case in other non .NET environments). And if you have the corresponding PDBs around, you will also have the source code line numbers.
Now, if you want to add some information to some exceptions, then of course you can do it, at carefully chosen places (maybe places where real exceptions actually happened and you want to improve your code for future errors), but make sure you really add value to the original one (and make sure you also embark the original one as the inner exception, like you do in your sample).
So, I would say your sample code could be ok. It really depends on the "Custom error message" (and possibly exception custom properties - make sure they are serializable). It has to add value or meaning to help diagnose the problem. For exemple, this looks quite ok to me (could be improved):
string filePath = ... ;
try
{
CreateTheFile(filePath);
DoThisToTheFile(filePath);
DoThatToTheFile(filePath);
...
}
catch (Exception e)
{
throw new FileProcessException("I wasn't able to complete operation XYZ with the file at '" + filePath + "'.", e);
}
This doesn't:
string filePath = ... ;
try
{
CreateTheFile(filePath);
DoThisToTheFile(filePath);
DoThatToTheFile(filePath);
}
catch (Exception e)
{
throw new Exception("I wasn't able to do what I needed to do.", e);
}
Foreword: I consider this pattern to be usable only in certain conditions and with full understanding of its good and bad sides.
Statement 1: An exception is when a member fails to complete the task it is supposed to perform as indicated by its name. (Jeffry Richter, CLR via C# Fourth Edition)
Statement 2: Sometimes we want from a library member to a) Get a result or b) Tell us it's impossible and we don't care about all the details, we'll just send details to the library developers.
Conclusion from St.1, St.2: When implementing a library method we can wrap a general Exception and throw a Custom one, including the source one as its InnerException. In this case a developer using this member will need to catch just one exception and we'll still get debug information.
Case 1: You are implementing a library method and don't want to expose it's internals or you intend/assume to change it's internals in future.
public string GetConfig()
{
try
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "MyCompany.MyProduct.MyFile.cfg";
// ArgumentNullException
// ArgumentException
// FileLoadException
// FileNotFoundException
// BadImageFormatException
// NotImplementedException
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
// ArgumentException
// ArgumentNullException
using (StreamReader reader = new StreamReader(stream))
{
// OutOfMemoryException
// IOException
string result = reader.ReadToEnd();
}
return result;
// TODO: Read config parameter from DB 'Configuration'
}
catch (Exception ex)
{
throw new ConfigException("Unable to get configuration", ex);
}
}
It's a pretty solid code and you are sure it won't throw an exception ever. Because it's not supposed to. Are you sure? Or you'd wrap it into try-catch, just in case? Or you'd make a developer do this job? What if he doesn't care whether this method will succeed, may be he has a backup plan? May be he'll wrap call to this method to try-catch(Exception e) instead of you? I don't think so.
Pros:
You are hiding implementation details and are free to change it in future;
The callers don't have to catch whole bunch of different exceptions, if they care, they can look at the InnerException.
Cons:
You are losing stack trace (It may be not that important for a third-party library);
Case 2: You want to add information to exception. It's not directly the code you wrote in the question, but it's still catching a general Exception and I think this is important underestimated part of the Exception Handling facility.
catch (Exception ex)
{
ex.Data.Add(paramName);
throw;
}
Addition:
I would edit your pattern in the following way:
try
{
// code that can cause various exceptions...
}
catch (Exception e)
{
if (e is ThreadAbortException || e is StackOverflowException || e is OutOfMemoryException)
{
throw;
}
throw new MyCustomException("Custom error message", e);
}
Summary:
This pattern can be used when developing a library public method to hide implementation details and simplify its using by developers.
The general principal with Exceptions is to catch them and handle them locally if applicable and otherwise allow them to bubble up to the top level container.
It all depends on the context that your application is running in. For example if the application is an ASP.Net web application then certain exceptions can be handled by the ASP application server in IIS but expected application specific errors (ones that are defined in your own interfaces) should be caught and presented to the end user if appropriate.
If you are dealing with I/O then there are a lot of factors that are beyond your control (network availability, disk hardware, etc.) so if there is a failure here then it is a good idea to deal with it straight away by catching the exception and presenting the user with and error message.
Most importantly don't fail silently so don't wrap the exceptions in your own exception and then ignore them. Better to allow them to bubble up and find them in the web server log for example.
After reading the question, answers and the comments posted, I think a thorough answer by Iain Galloway could explain much of it in broader way.
My short and sweet point to explain it,
The exceptions should be caught and custom exception should only be thrown when you want to hide the technical details from the end user and want only user to get informed that something failed with some proper message but on the other hand would always log the same exception to the log file so that we can provide some technical assistance and help to the user if the same scenario occurs frequently and from the log file we get the information that we need (technically).
You explicitly catch some exception type and know the exact scenario in what case the exception is thrown by the method and then handle it and have some predefined codes that can explain the error in the other methods calling the function and have some actions to take on that error codes.
This could rather help if you call many functions and they all throw some pre-defined exception with exception codes which can help categorizing them and take some actions accordingly.
In some other comment you mentioned, what about system critical exceptions like OutOfMemoryException you would only be able to catch those exception if you have explicitly added, [HandleProcessCorruptedStateExceptions] section over the function and to get detail answer in what scenario you should handle it read this SO post
The main thing it depends on is where your are catching the exception. In general libraries should be more conservative with catching exceptions whereas at the top level of your program (e.g. in your main method or in the top of the action method in a controller, etc) you can be more liberal with what you catch.
The reason for this is that e.g. you don't want to catch all exceptions in a library because you may mask problems that have nothing to do with your library, like "OutOfMemoryException" which you really would prefer bubbles up so that the user can be notified, etc. On the other hand, if you are talking about catching exceptions inside your main() method which catches the exception, displays it and then exits... well, it's probably safe to catch just about any exception here.
The most important rule about catching all exceptions is that you should never just swallow all exceptions silently... e.g. something like this in Java:
try {
something();
}
catch (Exception ex) {}
or this in Python:
try:
something()
except:
pass
Because these can be some of the hardest issues to track down.
A good rule of thumb is that you should only catch exceptions that you can properly deal with yourself. If you cannot handle the exception completely then you should let it bubble up to someone who can
Depends on what you have to do with when exception arises. If you wish to globally handle all the exceptions, that's OK to re-throw the exception to the caller method and let it handle the exceptions. But there are many scenarios where exceptions must be handled locally, in such cases, catching exception with known types should be preferred and a last catch should catch Exception ex (to catch an unexpected exception) and re-throw the exception to caller.
try
{
// code that can cause various exceptions...
}
catch (ArithmeticException e)
{
//handle arithmetic exception
}
catch (IntegerOverflowException e)
{
//handle overflow exception
}
catch (CustomException e)
{
//handle your custom exception if thrown from try{} on meeting certain conditions.
}
catch (Exception e)
{
throw new Exception(e); //handle this in the caller method
}
It might be good practice or might not depending on the scenario. Though I am not an expert here, to my knowledge I consider doing this is fine when you are not sure about exception. I see you are considering a code in try that can throw multiple exceptions. If you are not sure about which exception can be thrown, it is always better to do it the way you have done it. Anyway the execution will not allow you to execute multiple catch blocks. Whenever you hit first catch block, control will go to finally or wherever next you want it to go but definitely not another catch block.
First universal rule - Never swallow exceptions !! When you write a piece of code, you should be able to predict most of the cases where there could be an exception, and requires to be notified, such cases should be handled in the code. You should have a general logging module, that logs any exception caught by the application, but might not be of any use to the user actually.
Show the errors that are relevant to the user, for example the user of the system might not understand IndexOutOfRange exception, but it might be an interesting subject for us to research on why this occurred.
We need to always know what went wrong and when so that we could analyze the root cause and prevent it from happening again, because if it could happen once. It will happen again and may be it could cause a disaster. The only way to find what is wrong is by logging in what ever error the application encounters.
You can use ellipses too.
catch (...)
{
// catches all exceptions, not already catches by a catch block before
// can be used to catch exception of unknown or irrelevant type
}
Except this what you can do is
nested try-catch
try
{
//some code which is not for database related
try
{
//database related code with connection open
}
catch(//database related exception)
{
//statement to terminate
}
**finally()
{
//close connection,destroy object
}**
}
catch(//general exception)
{
//statement to terminate
}
According to me,
this would help you to get more concise idea of your error type.
I think that this issue is very speculative, it often depends on specific case, but I did some research and I will share it. First, I want to express my opinion on code from lain Galloway:
try {
GetDataFromNetwork("htt[://www.foo.com"); // FormatException?
GetDataFromNetwork(uriArray[0]); // ArrayIndexOutOfBounds?
GetDataFromNetwork(null); // ArgumentNull?
}
catch(Exception e)
{
throw new WeClearlyKnowBetterException(
"Hey, there's something wrong with your network!", e);
}
If GetDataFromNetwork could throw FormatException, than this external calling should has own method, in which will be handled that exception and it should be converted into custom exception like here:
try {
GetDataFromNetwork();
} catch (FormatException ex) {
// here you should wrap exception and add custom message, which will specify occuring problem
}
When I´m creating custom exception for specific application, I extend MyGeneralException from Exception and every more specific exception will extend MyGeneralException. So, at the moment you are wrap into custom exception, you should then put in the method throws MyGeneralException.
I´m using rule, which I took over from more experienced developers than I am, that at the first place, when could be thrown some foreign exception, there it should be wrappped into custom, because you don´t want to be dependent on the other module´s exception.
Then If you will use method anywhere, you will put only MyGeneralException into method signature throws and it will bubble up through the layers of application. It should be catched and processed at the highest level, mostly exception message is used to creating response by some handler, or it could be handled manually.
Mainly during designing exception handling there should be considered, if your library will use third party developers, they are not interest in processing many exceptions.
I don't quite get the topic "proper exception handling" into my head.
"Exceptions should only be caught only if you can do something to fix
that exceptional situation".
I don't understand this. For example:
If I do not catch FormatException thrown by Convert.toInt(), even if it's just to show the exception message to the user, my program just crashes. If I had caught this exception and just told the user that the input had the wrong format, it would have survived.
So, should I catch such exceptions or not?
Exceptions should only be caught only if you can do something to fix
that exceptional situation
fixing maybe not the best word here. You should catch exception if you can handle it. Handling may mean:
fixing problem or returning some default values
retrying something
logging or notifying user (I believe every exception should be logged, even if you can fix it)
throwing more high-level exception
But you should not catch exceptions and do nothing:
catch(FormatException ex)
{
}
That just swallows exception and you will never know if something bad happened.
It doesn't means that you let the exception unhandled. It means that the proper flow of application is not possible therefore the code should return and notify the caller (an exception or a message). And in your case as the input is invalid therefore you should handle the exception and let the caller know of what is wrong here.
This is a difficult one to answer and it of course depends on your design, application preferences.
When handling exceptions I try to follow these rules:
Only catch an exception I can handle and recover from (for example send a notification email). It's possible for the application to continue doing it's task and simply not notify the user - you don't want the process it's notifying to crash simply because your email server is down.
Don't program by exception, use a int.TryParse( ) by preference to check rather than relying on exceptions to dictate the program flow.
Always catch exceptions before they hit the service boundary. This may be the UI, a WebService or some interface. You should not show a user an exception, instead it should be logged and a pretty user friendly message (or error code) returned to the consumer.
Of course everyone has different opinions on error handling so it's difficult to get a definitive answer. My suggestion would be to build up your own set of rules (unless someone is paying you in which case follow theirs!).
In other words, do not catch exceptions you do not know how to handle. Ultimately any exception should be handled at some point (so your program does not crash) but you should have a sound strategy when and how to do it.
Yes, I think you should catch this exception because actually you can treat it in you catch block by warning the user his input has wrong format.
There's other solutions to avoid the possibility to have a format exception like for example if you ask for an integer and your application's a WPF/Winform/Web application you can use a NumericUpDown control in order to ensure the user enter an integer. Also you can use this kind of code so you won't have to manage exceptions :
if (int.TryParse(userEnteredValue, out resultInt))
{
}
If I do not catch FormatException thrown by Convert.toInt(), even if it's just to show the exception message to the user, my program just crashes.
Right, and this is a case of an exception which can be handled properly. bad input from a user is expected to occur, this, you should handle it.
There are other classes of errors though, things which you can do little about. For example, an OutOfMemoryException.
"Fixing" this situation is not necessarily correcting it. When you catch an error and inform the user about this error, that might be sufficient to "fix" it. E. g. you can let the user correct the input.
Your quote means that you should not do something like this:
try
{
// do something which can throw
}
catch(Exception ex) // even this is bad practice as you should try to catch specific exceptions
{
// do nothing
}
It depends on what the usability you can provide to the user while catching that particular exception.
Let's say you are doing some calculation based on the paramters entered by the user and there is one field that is optional.
Now, if the user enters some string for that field instead of numeric field, your program will crash, if you have not caught exception.
Bu, even if you caught that exception, you calculation will not be completed as you will be skipping the calculation after the exception is thrown.
But what you can do in this situation is, check if FormatException is thrown for that optional field. If yes, ignore the exception using a catch and set the value to some default value, say 0 and then proceed as usual with you calculation.
while maintaining my colleague's code from even someone who claims to be a senior developer, I often see the following code:
try
{
//do something
}
catch
{
//Do nothing
}
or sometimes they write logging information to log files like following try catch block
try
{
//do some work
}
catch(Exception exception)
{
WriteException2LogFile(exception);
}
I am just wondering if what they have done is the best practice? It makes me confused because in my thinking users should know what happens with the system.
My exception-handling strategy is:
To catch all unhandled exceptions by hooking to the Application.ThreadException event, then decide:
For a UI application: to pop it to the user with an apology message (WinForms)
For a Service or a Console application: log it to a file (service or console)
Then I always enclose every piece of code that is run externally in try/catch :
All events fired by the WinForms infrastructure (Load, Click, SelectedChanged...)
All events fired by third party components
Then I enclose in 'try/catch'
All the operations that I know might not work all the time (IO operations, calculations with a potential zero division...). In such a case, I throw a new ApplicationException("custom message", innerException) to keep track of what really happened
Additionally, I try my best to sort exceptions correctly. There are exceptions which:
need to be shown to the user immediately
require some extra processing to put things together when they happen to avoid cascading problems (ie: put .EndUpdate in the finally section during a TreeView fill)
the user does not care, but it is important to know what happened. So I always log them:
In the event log
or in a .log file on the disk
It is a good practice to design some static methods to handle exceptions in the application top level error handlers.
I also force myself to try to:
Remember ALL exceptions are bubbled up to the top level. It is not necessary to put exception handlers everywhere.
Reusable or deep called functions does not need to display or log exceptions : they are either bubbled up automatically or rethrown with some custom messages in my exception handlers.
So finally:
Bad:
// DON'T DO THIS; ITS BAD
try
{
...
}
catch
{
// only air...
}
Useless:
// DON'T DO THIS; IT'S USELESS
try
{
...
}
catch(Exception ex)
{
throw ex;
}
Having a try finally without a catch is perfectly valid:
try
{
listView1.BeginUpdate();
// If an exception occurs in the following code, then the finally will be executed
// and the exception will be thrown
...
}
finally
{
// I WANT THIS CODE TO RUN EVENTUALLY REGARDLESS AN EXCEPTION OCCURRED OR NOT
listView1.EndUpdate();
}
What I do at the top level:
// i.e When the user clicks on a button
try
{
...
}
catch(Exception ex)
{
ex.Log(); // Log exception
-- OR --
ex.Log().Display(); // Log exception, then show it to the user with apologies...
}
What I do in some called functions:
// Calculation module
try
{
...
}
catch(Exception ex)
{
// Add useful information to the exception
throw new ApplicationException("Something wrong happened in the calculation module:", ex);
}
// IO module
try
{
...
}
catch(Exception ex)
{
throw new ApplicationException(string.Format("I cannot write the file {0} to {1}", fileName, directoryName), ex);
}
There is a lot to do with exception handling (Custom Exceptions) but those rules that I try to keep in mind are enough for the simple applications I do.
Here is an example of extensions methods to handle caught exceptions a comfortable way. They are implemented in a way they can be chained together, and it is very easy to add your own caught exception processing.
// Usage:
try
{
// boom
}
catch(Exception ex)
{
// Only log exception
ex.Log();
-- OR --
// Only display exception
ex.Display();
-- OR --
// Log, then display exception
ex.Log().Display();
-- OR --
// Add some user-friendly message to an exception
new ApplicationException("Unable to calculate !", ex).Log().Display();
}
// Extension methods
internal static Exception Log(this Exception ex)
{
File.AppendAllText("CaughtExceptions" + DateTime.Now.ToString("yyyy-MM-dd") + ".log", DateTime.Now.ToString("HH:mm:ss") + ": " + ex.Message + "\n" + ex.ToString() + "\n");
return ex;
}
internal static Exception Display(this Exception ex, string msg = null, MessageBoxImage img = MessageBoxImage.Error)
{
MessageBox.Show(msg ?? ex.Message, "", MessageBoxButton.OK, img);
return ex;
}
Best practice is that exception handling should never hide issues. This means that try-catch blocks should be extremely rare.
There are 3 circumstances where using a try-catch makes sense.
Always deal with known exceptions as low-down as you can. However, if you're expecting an exception it's usually better practice to test for it first. For instance parse, formatting and arithmetic exceptions are nearly always better handled by logic checks first, rather than a specific try-catch.
If you need to do something on an exception (for instance logging or roll back a transaction) then re-throw the exception.
Always deal with unknown exceptions as high-up as you can - the only code that should consume an exception and not re-throw it should be the UI or public API.
Suppose you're connecting to a remote API, here you know to expect certain errors (and have things to in those circumstances), so this is case 1:
try
{
remoteApi.Connect()
}
catch(ApiConnectionSecurityException ex)
{
// User's security details have expired
return false;
}
return true;
Note that no other exceptions are caught, as they are not expected.
Now suppose that you're trying to save something to the database. We have to roll it back if it fails, so we have case 2:
try
{
DBConnection.Save();
}
catch
{
// Roll back the DB changes so they aren't corrupted on ANY exception
DBConnection.Rollback();
// Re-throw the exception, it's critical that the user knows that it failed to save
throw;
}
Note that we re-throw the exception - the code higher up still needs to know that something has failed.
Finally we have the UI - here we don't want to have completely unhandled exceptions, but we don't want to hide them either. Here we have an example of case 3:
try
{
// Do something
}
catch(Exception ex)
{
// Log exception for developers
WriteException2LogFile(ex);
// Display message to users
DisplayWarningBox("An error has occurred, please contact support!");
}
However, most API or UI frameworks have generic ways of doing case 3. For instance ASP.Net has a yellow error screen that dumps the exception details, but that can be replaced with a more generic message in the production environment. Following those is best practice because it saves you a lot of code, but also because error logging and display should be config decisions rather than hard-coded.
This all means that case 1 (known exceptions) and case 3 (one-off UI handling) both have better patterns (avoid the expected error or hand error handling off to the UI).
Even case 2 can be replaced by better patterns, for instance transaction scopes (using blocks that rollback any transaction not committed during the block) make it harder for developers to get the best practice pattern wrong.
For instance suppose you have a large scale ASP.Net application. Error logging can be via ELMAH, error display can be an informative YSoD locally and a nice localised message in production. Database connections can all be via transaction scopes and using blocks. You don't need a single try-catch block.
TL;DR: Best practice is actually to not use try-catch blocks at all.
An exception is a blocking error.
First of all, the best practice should be don't throw exceptions for any kind of error, unless it's a blocking error.
If the error is blocking, then throw the exception. Once the exception is already thrown, there's no need to hide it because it's exceptional; let the user know about it (you should reformat the whole exception to something useful to the user in the UI).
Your job as software developer is to endeavour to prevent an exceptional case where some parameter or runtime situation may end in an exception. That is, exceptions mustn't be muted, but these must be avoided.
For example, if you know that some integer input could come with an invalid format, use int.TryParse instead of int.Parse. There is a lot of cases where you can do this instead of just saying "if it fails, simply throw an exception".
Throwing exceptions is expensive.
If, after all, an exception is thrown, instead of writing the exception to the log once it has been thrown, one of best practices is catching it in a first-chance exception handler. For example:
ASP.NET: Global.asax Application_Error
Others: AppDomain.FirstChanceException event.
My stance is that local try/catches are better suited for handling special cases where you may translate an exception into another, or when you want to "mute" it for a very, very, very, very, very special case (a library bug throwing an unrelated exception that you need to mute in order to workaround the whole bug).
For the rest of the cases:
Try to avoid exceptions.
If this isn't possible: first-chance exception handlers.
Or use a PostSharp aspect (AOP).
Answering to #thewhiteambit on some comment...
#thewhiteambit said:
Exceptions are not Fatal-Errors, they are Exceptions! Sometimes they
are not even Errors, but to consider them Fatal-Errors is completely
false understanding of what Exceptions are.
First of all, how an exception can't be even an error?
No database connection => exception.
Invalid string format to parse to some type => exception
Trying to parse JSON and while input isn't actually JSON => exception
Argument null while object was expected => exception
Some library has a bug => throws an unexpected exception
There's a socket connection and it gets disconnected. Then you try to send a message => exception
...
We might list 1k cases of when an exception is thrown, and after all, any of the possible cases will be an error.
An exception is an error, because at the end of the day it is an object which collects diagnostic information -- it has a message and it happens when something goes wrong.
No one would throw an exception when there's no exceptional case. Exceptions should be blocking errors because once they're thrown, if you don't try to fall into the use try/catch and exceptions to implement control flow they mean your application/service will stop the operation that entered into an exceptional case.
Also, I suggest everyone to check the fail-fast paradigm published by Martin Fowler (and written by Jim Shore). This is how I always understood how to handle exceptions, even before I got to this document some time ago.
[...] consider them Fatal-Errors is completely false understanding of what exceptions are.
Usually exceptions cut some operation flow and they're handled to convert them to human-understandable errors. Thus, it seems like an exception actually is a better paradigm to handle error cases and work on them to avoid an application/service complete crash and notify the user/consumer that something went wrong.
More answers about #thewhiteambit concerns
For example in case of a missing Database-Connection the program could
exceptionally continue with writing to a local file and send the
changes to the Database once it is available again. Your invalid
String-To-Number casting could be tried to parse again with
language-local interpretation on Exception, like as you try default
English language to Parse("1,5") fails and you try it with German
interpretation again which is completely fine because we use comma
instead of point as separator. You see these Exceptions must not even
be blocking, they only need some Exception-handling.
If your app might work offline without persisting data to database, you shouldn't use exceptions, as implementing control flow using try/catch is considered as an anti-pattern. Offline work is a possible use case, so you implement control flow to check if database is accessible or not, you don't wait until it's unreachable.
The parsing thing is also an expected case (not EXCEPTIONAL CASE). If you expect this, you don't use exceptions to do control flow!. You get some metadata from the user to know what his/her culture is and you use formatters for this! .NET supports this and other environments too, and an exception because number formatting must be avoided if you expect a culture-specific usage of your application/service.
An unhandled Exception usually becomes an Error, but Exceptions itself
are not codeproject.com/Articles/15921/Not-All-Exceptions-Are-Errors
This article is just an opinion or a point of view of the author.
Since Wikipedia can be also just the opinion of articule author(s), I wouldn't say it's the dogma, but check what Coding by exception article says somewhere in some paragraph:
[...] Using these exceptions to handle specific errors that arise to
continue the program is called coding by exception. This anti-pattern can quickly degrade software in performance and maintainability.
It also says somewhere:
Incorrect exception usage
Often coding by exception can lead to further issues in the software
with incorrect exception usage. In addition to using exception
handling for a unique problem, incorrect exception usage takes this
further by executing code even after the exception is raised. This
poor programming method resembles the goto method in many software
languages but only occurs after a problem in the software is detected.
Honestly, I believe that software can't be developed don't taking use cases seriously. If you know that...
Your database can go offline...
Some file can be locked...
Some formatting might be not supported...
Some domain validation might fail...
Your app should work in offline mode...
whatever use case...
...you won't use exceptions for that. You would support these use cases using regular control flow.
And if some unexpected use case isn't covered, your code will fail fast, because it'll throw an exception. Right, because an exception is an exceptional case.
In the other hand, and finally, sometimes you cover exceptional cases throwing expected exceptions, but you don't throw them to implement control flow. You do it because you want to notify upper layers that you don't support some use case or your code fails to work with some given arguments or environment data/properties.
The only time you should worry your users about something that happened in the code is if there is something they can or need to do to avoid the issue. If they can change data on a form, push a button or change a application setting in order to avoid the issue then let them know. But warnings or errors that the user has no ability to avoid just makes them lose confidence in your product.
Exceptions and Logs are for you, the developer, not your end user. Understanding the right thing to do when you catch each exception is far better than just applying some golden rule or rely on an application-wide safety net.
Mindless coding is the ONLY kind of wrong coding. The fact that you feel there is something better that can be done in those situations shows that you are invested in good coding, but avoid trying to stamp some generic rule in these situations and understand the reason for something to throw in the first place and what you can do to recover from it.
I know this is an old question, but nobody here mentioned the MSDN article, and it was the document that actually cleared it up for me, MSDN has a very good document on this, you should catch exceptions when the following conditions are true:
You have a good understanding of why the exception might be thrown, and you can implement a specific recovery, such as prompting the user to enter a new file name when you catch a FileNotFoundException object.
You can create and throw a new, more specific exception.
int GetInt(int[] array, int index)
{
try
{
return array[index];
}
catch(System.IndexOutOfRangeException e)
{
throw new System.ArgumentOutOfRangeException(
"Parameter index is out of range.");
}
}
You want to partially handle an exception before passing it on for additional handling. In the following example, a catch block is used to add an entry to an error log before re-throwing the exception.
try
{
// Try to access a resource.
}
catch (System.UnauthorizedAccessException e)
{
// Call a custom error logging procedure.
LogError(e);
// Re-throw the error.
throw;
}
I'd suggest reading the entire "Exceptions and Exception Handling" section and also Best Practices for Exceptions.
The better approach is the second one (the one in which you specify the exception type). The advantage of this is that you know that this type of exception can occur in your code. You are handling this type of exception and you can resume. If any other exception came, then that means something is wrong which will help you find bugs in your code. The application will eventually crash, but you will come to know that there is something you missed (bug) which needs to be fixed.
With Exceptions, I try the following:
First, I catch special types of exceptions like division by zero, IO operations, and so on and write code according to that. For example, a division by zero, depending the provenience of the values I could alert the user (example a simple calculator in that in a middle calculation (not the arguments) arrives in a division by zero) or to silently treat that exception, logging it and continue processing.
Then I try to catch the remaining exceptions and log them. If possible allow the execution of code, otherwise alert the user that a error happened and ask them to mail a error report.
In code, something like this:
try{
//Some code here
}
catch(DivideByZeroException dz){
AlerUserDivideByZerohappened();
}
catch(Exception e){
treatGeneralException(e);
}
finally{
//if a IO operation here i close the hanging handlers for example
}
The second approach is a good one.
If you don't want to show the error and confuse the user of application by showing runtime exception(i.e. error) which is not related to them, then just log error and the technical team can look for the issue and resolve it.
try
{
//do some work
}
catch(Exception exception)
{
WriteException2LogFile(exception);//it will write the or log the error in a text file
}
I recommend that you go for the second approach for your whole application.
Leave blank catch block is the worse thing to do. If there is an error the best way to handle it is to:
Log it into file\database etc..
Try to fix it on the fly (maybe trying alternative way of doing that operation)
If we cannot fix that, notify the user that there is some error and of course abort the operation
To me, handling exception can be seen as business rule. Obviously, the first approach is unacceptable. The second one is better one and it might be 100% correct way IF the context says so. Now, for example, you are developing an Outlook Addin. If you addin throws unhandled exception, the outlook user might now know it since the outlook will not destroy itself because of one plugin failed. And you have hard time to figure out what went wrong. Therefore, the second approach in this case, to me, it is a correct one. Beside logging the exception, you might decide to display error message to user - i consider it as a business rule.
Best practice is to throw an Exception when the error occurs. Because an error has occurred and it should not be hidden.
But in real life you can have several situations when you want to hide this
You rely on third party component and you want to continue the program in case of error.
You have a business case that you need to continue in case of error
You should consider these Design Guidelines for Exceptions
Exception Throwing
Using Standard Exception Types
Exceptions and Performance
https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/exceptions
The catch without any arguments is simply eating the exception and is of no use. What if a fatal error occurs? There's no way to know what happened if you use catch without argument.
A catch statement should catch more specific Exceptions like FileNotFoundException and then at the very end you should catch Exception which would catch any other exception and log them.
Sometimes you need to treat exceptions which say nothing to users.
My way is:
To catch uncaughted exceptions on application level (ie. in global.asax) for critical exceptions (application can not be useful). These exeptions I am not catching on the place. Just log them on app level and let system do its job.
Catch "on place" and show some useful info to user (entered wrong number, can't parse).
Catch on place and do nothing on marginal problems like "I will check for update info on the background, but the service is not running".
It definitely does not have to be best practice. ;-)
I can tell you something:
Snippet #1 is not acceptable because it's ignoring exception. (it's swallowing it like nothing happened).
So do not add catch block that do nothing or just rethrows.
Catch block should add some value. For example output message to end user or log error.
Do not use exception for normal flow program logic. For example:
e.g input validation. <- This is not valid exceptional situation, rather you should write method IsValid(myInput); to check whether input item is valid or not.
Design code to avoid exception. For example:
int Parse(string input);
If we pass value that cannot be parsed to int, this method would throw and exception, instead of that we might write something like this:
bool TryParse(string input,out int result); <- this method would return boolean indicating if parse was successfull.
Maybe this is little bit out of scope of this question, but I hope this will help you to make right decisions when it's about try {} catch(){} and exceptions.
My software uses Try Catch to catch errors; recently an error occurred (a timeout connection to the database) and a Messagebox.Show() pops up alerting the user of the issue. The end users of this in house software are not IT literate at all. The lady who received this message asked me with whom she had lost a connection with (I honestly think she thought it was a spiritual 'connection' since she looks like a hippy).
So what I would like to do is simplify the error messages.
Things I've considered:
I could check/compare the ex.Message string to a list of strings I want to cater for and if it matches one I will display the simplified version. IMO, not realistic.
I then thought having multiple catches, and if it's of a certain type, to display the simple message. But how messy is my code going to be! Not only that, it's also probably going to end up with misleading messages as not all (eg) TimeOutExceptions are the same.
Or, I have to try and write my own Exception type to cater for this.
I then though it would be really handy if each .NET exception had an associated ID - that way, I could write a nice case statement with each ID and my own nice and easy to ready/understand message.
Has anyone else considered this before and did they find any suitable arrangements. Or is it better to just put a message on screen saying "Error - an email has been sent to the software vendor...")?
You should never display Exception.message to end users. This is informational text that helps to identify the kind of error.
Anytime you catch the exception, you are supposed to handle it properly or rethrow/throw another. If you are at the point of code that handles the exception by displaying some error message, you should be able to infer the context properly from the Exception itself. You can use proper exception types to create some basic exception domain (DatabaseException, CommunicationException) and the use error codes that discriminate the exception further within its domain.
You can use Data property which belongs to Exception class and is type of IDictionary, thus serving as Exception state bag. You can then store here something like 'ERR_CODE' = CONSTANT and have some single point of exception handling that will check the error code and if it's present, handle the exception with some user friendly output.
You can even register global exception handler within current AppDomain to catch any uncaught exception and display some message. This is common practice, but you must be aware that this approach breaks the natural code-flow and if such thing happens, you are left with handled exception but non-caught exception flow (you didn't handle the exception on the caller site which then doesn't know that the call failed and may behave unpredictable). So use this approach only by printing some user friendly message and ending application or terminating current Usecase.
If ever you write code like catch (Exception ex) then you are doing something wrong. You should always catch specific exceptions for coding situations that are exceptional.
Have a read of Eric Lippert's "Vexing exceptions" blog entry.
Catching exceptions and just displaying the message is in the "boneheaded" category of exceptions. You should never have them.
Instead you should only have exceptions of the other three types expounded by Eric. And you should catch the specific exception type involved, not the generic Exception type.
If you catch specific exceptions then you can present a very reasonable message to the end user - even providing information about how to solve the problem.
Better still, without all the generic exception catching your code will be easier to debug, cleaner and more terse. The major predictor for bugs in code is the actual lines of code you write. Write less code and have less bugs.
So my suggestion is change your code design and handle the exceptions appropriately.
In general, you will need to handle the exception by its type (e.g. catch (SomeSpecificException))
Certain derived exception types do have additional codes, e.g.
e.g. SqlException has a Number property which can be used for control flow / information
catch (System.Data.SqlClient.SqlException sqlEx)
{
if (sqlEx.Number == 1205) // Deadlock
...
if (sqlEx.Number == -2) // = TimeOut
...
// etc.
}
Edit
Actually, System.Exception does have a protected HRESULT property. See How do I determine the HResult for a System.IO.IOException? and
How to get Exception Error Code in C#
Although it isn't directly accessible, you can retrieve it via Marshal.GetHRForException(ex). Different exceptions have different HRESULTs, e.g.
System.Exception : HRESULT COR_E_EXCEPTION (0x80131500)
System.SystemException : HRESULT COR_E_SYSTEM (0x80131501)
That said, as per other answers, catching specific exceptions is still the preferred mechanism IMO - presumably the HRESULT mechanism is a COM hangover.
You should handle and provide meaningful message for those exceptions only you anticipate might arise in your code and the exception can be handled. Any exception you do not anticipate, display a generic message and log the message to log file or event log. You may also want to setup a policy for the unhandled/unexpected exceptions such that display message to contact support and exit application.
Please consider the following piece of code, which throws three different exceptions (namely, System.Configuration.ConfigurationErrorsException, System.FormatException and System.OverflowException):
int SomeInt = Convert.ToInt32(ConfigurationManager.AppSettings["SomeIntValue"]);
The exceptions are different, and so in practice I should have three different catch blocks to handle each particular exception. However, in this particular case, all exceptions are handled the same way: a log is written to, say, EventViewer, and a message informing of a configuration error is displayed... In this particular cause, is it too bad to use
try
{
int SomeInt = ConfigurationManager.AppSettings["SomeIntValue"];
}
catch (Exception ThisException)
{
/* Log and display error message. */
}
or should I, instead, use the three catch blocks and repeat the code within each of them?
See C# Exception Handling Fall Through for a discussion around this problem.
In short, if you catch the general Exception you should check if it is one of the expected types and if not rethrow it.
Update(and a bit out of scope)
Also there are a few times I think it's valid to do a catch all. This is very rare but sometimes in webservices or if you do something on the background thread in asp.net as and exception there will restart the whole application and people might lose their session if you have taken a dependency on that.
It is bad practice to catch System.Exception . . . or better yet, it is bad practice to handle System.Exception anywhere but the top level of your application. What you should to is:
Catch System.Exception
Test the exception for the types you plan to handle identically
Rethrow if it's not one of those.
Example code:
catch (Exception ex)
{
if (ex is FormatException || ex is OverflowException || ex is ConfigurationErrorsException) {
CommonHandler();
}
else {
throw;
}
}
I don't think it's bad practice. If your desired functionality is "whenever this code throws an exception, then take these actions" then I think catching System.Exception is perfectly appropriate.
The fact that you're wrapping a very specific framework function instead of a large block of custom code helps in my opinion as well.
What is really needed, but the .net exception hierarchy doesn't provide, is a clean way of distinguishing exceptions which mean "The requested operation didn't happen, but the system state is essentially fine except to the extent implied by the operation not having happened" from those which mean "The CPU is on fire, and even trying to save the current user's work would likely as not make things worse." There are a lot of contexts in which one really should endeavor to catch all exceptions of the first type, while ideally not catching those of the second. While there a few gradations beyond the two above, generally when catching exceptions one doesn't really care about the distinction between an InvalidArgumentException or an InvalidOperationException; what one cares about is whether the overall system state is valid or corrupted.
As it is, if one is making a call to e.g. a file-import plug-in and it throws an exception, I'm not really sure one can do except try to catch and rethrow really bad exceptions, while having all other exceptions put up a "This file could not be opened" dialog box. Hopefully the state of the system at that point is essentially as it would be had the user not tried to open the file, but without some standardized way of indicating exception severity, I don't think there's any way to be sure.
Incidentally, if I had my druthers, there would be a class ExceptionBase, from which all exceptions would derive; most exceptions would derive from Exception (which would in turn derive from ExceptionBase) but things like ThreadAbortException, StackOverflowException, OutOfMemoryException, etc. would be derived from CriticalException. That way one could catch most 'unexpected' exceptions without accidentally stifling the really bad ones.
It is not necessarily bad practice, the bad practice usually occurs when you do silly things in the catch block. Catching the base exception class is a good safety measure assuming you need to do something when the error occurs. The case for catching a specific exception class is best manifest when that specific class gives you information you can act on, catching SqlException for example can help you look at certain properties specific to that class and let you act on the problem.
Often times people will catch an exception and do something silly like create a new exception or even worse, swallow the exception details.
An often missed pattern is that you can catch, act an rethrow.
catch(Exception ex)
{
//do something
throw;
}
thus preserving the exception details.
In this particular case, it is entirely possible to use different catch blocks, as you do have different actions you can take depending on what exception you get.
For the first two you can set a reasonable default silently as to not annoy the user needlessly, then hope the problem fixes itself when you save your file, and for the latter exception you can ask the user if he wants to continue with the loading process (in which case you set a reasonable default), since the configuration file is obviously corrupted.
In general, the thinking is this: Do I need to take different actions in regards to different kinds of exceptions being thrown? More often than not, the answer is no, so a blank catch(Exception ex){ /* log... */ } (or even no catch at all if the exception is invariably fatal) is enough.
Edit: Blank as in blank check, not empty block :)