Handling of exceptions, do I have to catch each specific exception? - c#

Just a thing I've been thinking of for a while. Do I need to handle KeyNotFoundException by catching that specific exception or can I just use a "blank" catch like this:
try
{
//Code goes here
}
catch
{
}
Or do I have to do it like this:
try
{
//Code goes here
}
catch(Exception ex)
{
}
Or do I have to do it like this:
try
{
//Code goes here
}
catch(KeyNotFoundException ex)
{
}
The reason why I ask is that when I look at crash count at App Hub I have a lot of crashes related to "KeyNotFoundException" but I never experience any crashes in my app. Could this be the problem, that I don't catch the specific exception and that App Hub crash statistics classifies it as a crash even if the exception is handled?
EDIT:
Here are some screenshots of the App Hub crash statistics (Stack Trace). Does anyone know ehat in detail it means? It has to do with my background agent and that might be the reason for why I never experience any crashes in my app:

No, the marketplace is counting only unhandled exceptions, so your app does crash.
An empty catch or catching Exceptions are the most general catches (Every exception is derived from the Exception base class, so you're catching everything.), the critical code is somewhere you don't use try-catch. Based on the exception you should check your dictionaries and think about what are the conditions which can cause error.
Generally a good practice is to check the correctness of parameters in your public methods so if any problem occurs you can provide yourself more helpful error messages, for example:
public User GetUser(string username)
{
if (String.IsNullOrEmpty(username))
throw ArgumentNullException("username");
return this.users[username];
}
In this case if things goes wrong you will see that you used a null for username, otherwise you would see a KeyNotFoundException. Hope this helps, good luck!

You can use a base exception to catch a more derived exception, so Exception will catch KeyNotFoundException because the latter inherits the former. So strictly speaking, if you want to catch "any" exception, catch (Exception) will suffice.
However, you should only catch exceptions if you can handle them in some meaningful manner. Though I'm not sure how this mindset stacks up against WP development.
As for your underlying problem, I've no idea. Does the App Hub not provide any details around the crash such as stack traces?
Your best bet is to leave the template code in place that registers for the unhandled exceptions event and put some logging into your application to record as much detail as you can about the state of the app during the crash.

No, you do not have to catch each specific exception type in a try / catch block, see the C# language reference.
However, rather than wrapping all your code in try / catch blocks, you probably want to add exception handling logic and logging into a handler for the Application.UnhandledException event. See this excellent blog post for an example of how to handle this event.

If you are interested in a specific exception, such as KeyNotFoundException in a particular part of the code then you catch it like this
try
{
//Code goes here
}
catch(KeyNotFoundException ex)
{
}
If you want to catch a specific exception and some undefined one you do something like this
try
{
//Code goes here
}
catch(KeyNotFoundException ex)
{
}
catch(Exception ex)
{
}
If you want to make sure your application doesn't crash use Collin's example with the Application.UnhandledException event.

You can catch all exceptions by catching the base class, but whether you want to depends on what your trying to achieve.
Generally speaking, you should only catch an exception at a level at which you have the knowledge to decide what should be done about the error, ie roll back some action, or display a message to the user. It is often the case that at a certain level it makes sense to catch a specific exception type, as that level of code understands what that means, but it may not make sense to catch all.
Avoid catching everything too soon, exceptions exist to tell you somethings wrong, blanket catching ignores that and can mean your program keeps running, but starts behaving wrong, possibly corrupting data. Its often better to "fail early and fail fast" when receiving unexpected exceptions.

As others have said - No - you dont need to catch the specific exception, catching Exception or just catch will prevent the exception from bubbling up.
However you should just catch specific exceptions where possible to make your code more explicit in what it is doing. Better again test for correctness before the potential error condition - again this is covered in other posts.
For your specific problem the link you posted seems to indicate that it is a problem with reading values from the isolated storage (IsolatedStorage.get_Item) - so wherever you access IsolatedStorage during from the ScheduledTaskAgent invocation you need to ensure the item exists before getting it. Perhaps there are some config settings missing or something?

Related

Where should I place try catch?

Learning to log errors.
This is a basic structure of code all through my project.
I have been advised that the try block has to be placed only in Event Handlers.
But when logging the error, it is required to know, which method caused the error.
So, in such cases, should I also keep try block in AllIsFine() & SaveData().
If yes, then should it log the error or just throw.
What is the best/Standard practice.
DataContext objDataContext = new DataContext();
protected void btn_Click(object sender, EventArgs e)
{
try
{
if(AllIsFine())
{
objDataContext.SaveData();
}
}
catch(Exception ex)
{
//some handling
}
}
private bool AllIsFine()
{
//some code
}
EDIT: Ofcourse, we would try to see that it never raises an exception, but not practical. I am looking at it this way. When deployed, the only access I have is to the logs and need to get as much info as possible.So in such cases, (and with this kind of a structure), where do you advise to keep the try catch
I have been advised that the try block has to be placed only in Event
Handlers
This is not true.
There are different type of exceptions, some you need to handle, some you should throw, some you should catch, some you should not. Read this please.
Summary:
You should catch exceptions that you can do something with them
If you want to just log exceptions catch, log, and then use throw not throw ex (it resets the call stack)
Prevent exception from happening if you can, check for conditions that prevent exceptions(IndexOutOfRangeException, NullPointerException, ArgumentNullException) do that instead of executing the action and catch the exception
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.
But when logging the error, it is required to know, which method
caused the error.
You should use the call stack for that.
Try as much as possible to Prevent the Exceptions, and not catching them, if you would Catch an error, try to catch a specific Error, what I mean by that, not try to Catch Exception but something like specific like InvalidCastException.
After catching an Error you should log the exception, but not throwing an exception to log it.
The try-catch statement consists of a try block followed by one or more catch clauses, which specify handlers for different exceptions.
object o2 = null;
try
{
int i2 = (int)o2; // Error
}
It is possible to use more than one specific catch clause in the same try-catch statement. A throw statement can be used in a catch block to re-throw the exception that is caught by the catch statement. You can catch one exception and throw a different exception. When you do this, specify the exception that you caught as the inner exception
catch (FileNotFoundException ex)
{
// FileNotFoundExceptions are handled here.
}
catch (InvalidCastException ex)
{
// Perform some action here, and then throw a new exception.
throw new YourCustomException("Put your error message here.", ex);
}
throw ex; is basically like throwing an exception from that point, so the stack trace would only go to where you are issuing the throw ex; statement
I thought about your question for a while and even if it is already answered, I wanted to share my thoughts.
general
When talking about exception handling, you have to keep in mind what an exception is:
An exception occurs when code cannot run as expected, causing an inconsistent behaviour/state of your application.
This thought leads us to an important rule: Do not catch exceptions that you can’t handle! The Exception system provides security. Think about an accounting software that connects to a database and the connection throws an exception. If you only log the exception and don’t provide any notification about this to the user, he will start to work with the software and when he tries to save, the data will be lost!
You see, it is important where to handle exceptions:
Some of them will be handled by the user (usually in the UI-Layer e.g. View in MVVM/MVC) like the Database exception from the example – only the user can decide if the database is required, the connection string has changed or if a retry will fix the issue.
Others can be handled where they occur; for example code that interacts with some sort of hardware often implements methods with some sort of retry or circuit-breaker logic.
architecture
The where decision is also influenced by the architecture:
Let’s come back to the Database exception scenario: You cannot handle specific exceptions like a MySQL specific Exception (MySqlException) in the UI-Layer because that causes a boundary from you View layer to the specific Model layer implementation and the layering architecture will be broken. However, this is not the topic since your question is about logging exceptions, but you should keep that in mind and probably think about it like this: Catch exceptions of concrete libraries or those that belong to a specific layer/dependency where they occur and log them there and throw new, more generic (probably self-created) exceptions. Those exceptions can be handled in the View-layer and presented to the user.
implementation
The question of where is also important. Since logging is seen as a cross cutting concern. You could think about an AOP framework or, as I have suggested in a comment, by using a decorator pattern. You can compose the logging decorators by basic inversion of control usage and your code will be much cleaner by wrapping everything in try-catch blocks.
If you are using (or planning to use) a DI-container in your application, you could also make use of interception, which would allow you to dynamically wrap you method calls by specified behaviour (like try-catch).
summary
handle your exceptions where you can handle them and log them where you get the most relevant data (e.g. context) from to reproduce the error. But keep in mind that an exception is a security mechanism – it will stop your application when it is no longer in a secure state – when you don’t forward your exceptions (by using throw) and just log them, this could cause not the best user experience.
If you want any code examples, simply ask for them ;)

C# exception handling, which catch clause to use? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Catching specific vs. generic exceptions in c#
Here's an example method
private static void outputDictionaryContentsByDescending(Dictionary<string, int> list)
{
try
{
//Outputs entire list in descending order
foreach (KeyValuePair<string, int> pair in list.OrderByDescending(key => key.Value))
{
Console.WriteLine("{0}, {1}", pair.Key, pair.Value);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Error detected", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
I would like to know what exception clause to use apart from just Exception and if there is an advantage in using more specific catch clauses.
Edit: O.k thanks everyone
Catching individual types of Exceptions in your statement will allow you to handle each in a different way.
A blanket rule for Exception may be useful for logging and rethrowing Exceptions, but isn't the best for actually handling Exceptions that you may be able to recover from.
try
{
// open a file specified by the user
}
catch(FileNotFoundException ex)
{
// notify user and re-prompt for file
}
catch(UnauthorizedAccessException ex)
{
// inform user they don't have access, either re-prompt or close dialog
}
catch(Exception ex)
{
Logger.LogException(ex);
throw;
}
You should only really catch exceptions that you are expecting that code may throw. That way, if it throws something you didn't expect, it may either be something critical; something that should bubble up the call stack and possibly crash the application; or something you have not thought of.
For example, you may wish to handle IOExceptions thrown by I/O code so that you can relay the problem back to the user. However, the same operations may throw something more critical such as an AccessViolationException. In this case, you might want the program to terminate, or handle the problem in a different way.
Generic exception handling should only really be used in cases where you do not care what error occurred, and subsequently don't want it affecting the rest of your process.
The only potential cause for an exception that I see in your example is if list is null. OrderByDescending() should return an empty IEnumerable<> rather than a null reference.
If I read that correctly, it might make more sense to catch NullReferenceException:
try
{
...
} catch (NullReferenceException exception)
{
MessageBox.Show(...);
}
However, this really depends on the needs of your application. If your intention is just to alert the user or to log all exceptions, catching the Exception class is fine. If you need special handling for different types of exceptions - such as sending an email alert instead of just logging the message - then it makes sense to use specific exception types:
try
{
}
catch(NullReferenceException e)
{
//...
}
catch(StackOverflowException e)
{
//...
}
catch(Exception e)
{
/// generic exception handler
}
Which exception to use really depends on the code in the try block. In general you want to catch exceptions that you can do something with and let exceptions you have no power over move to high levels of your code where you can perform some action that makes since. One of the most common mistakes I see people make is attempting to catch errors that they have no ability to handle.
for example
Void ChoseFile()
{
try
{
string FileName = GetInputFile()
}
catch( InvalidFileSelectedException ex)
{
//In this case we have some application specific exception
//There may be a business logic failure we have some ability
//to infomr the user or do an action that makes sense
}
catch(FileNotFoundException exfilenot found)
{
//In this case we can do somthing different the the above
}
catch(Exception )
{
//Normal I would not use this case we have an error we don't know what to do
//with. We may not have a usefull action. At best we can log this exception
// and rethrow it to a higher level of the application that can inform the user
// fail the attempted action. Catching here would only suppress the failure.
}
}
You should always catch exceptions with an as specific class as possible.
If you know what to do if a file is locked, but you regard all other errors as unexpected and impossible to handle, you should catch System.IO.IOException and deal with the error. You should only catch Exception (or just catch {) for gracefully exiting.
Since you are dealing with a Dictionary.. then you want to look at these 2 exceptions
The key of keyValuePair is a null reference (Nothing in Visual Basic).
ArgumentException An element with the same key already exists in the Dictionary(TKey, TValue).
KekValuePair Exception
This is taken from the MSDN site
Use the exception type that you might expect but still not be able to prevent and that you can adequately handle. Let anything else bubble up to somewhere that might expect it or can handle it.
In your case here, I might expect that I would run into a NullReferenceException if the dictionary is null. But I would not catch it. This is something I can validate against instead
if (dictionary != null)
So there is no reason to allow an exception to even happen. Never use exceptions for control flow, and validate against known causes.
Some classes/methods will throw different exceptions, depending on the error. For example, you might be using the File class to write data to a file. You could write multiple Catch statements for the exception types you could recover from, and a generic Exception catch to log and bubble up anything that can't be recovered from.
By using Exception you catch all exceptions. Of you use IOException or StackOverflowException you'll only catch errors of that type.
a StackOverflowException catched by a Exception still hold the same message, stack trace etc.
Exception handling philosophy
I am sure you can find many other philosophies
Code defensively. Catching exceptions is more expensive than preventing the error in the first place.
Don't catch an exception and bury it by not handling it. You can spend many hours trying to find an error that has been suppressed.
Do log errors that you catch.
This helps in analyzing the problem. You can check to see if more than one user is having the same problem
I prefer a database for logging, but a flat file, or the event log are also suitable.
The database solution is easiest to analyze but may introduce additional errors.
If the error is due to bad data entered by the user, inform the user of the problem and allow them to retry.
Always allow an escape route if they cannot fix the problem.
Catch the error as close to the source as possible
This could be a database procedure, a method in a data access layer (DAL) or some other location.
Handling the exception is different than catching it. You may need to rethrow the exception so that it can be handled higher up the stack or in the UI.
Rethrowing the exception can be done in at least two ways.
throw by itself does not alter the stack.
throw ex does alter or add to the stack with no benefit.
Sometimes it is best not to catch an exception, but rather let it bubble up.
If you are writing services (web or windows) that do not have a user interface (UI) then you should always log the error.
Again, this is so that someone can analyze the log or database file to determine what is happening.
You always want someone to know that an error has occurred.
Having a lot of catch statements for a try block can make your code more difficult to maintain, especially if the logic in your catch blocks is complex.
Instead, code defensively.
Remember that you can have try catch blocks within catch blocks.
Also, don't forget to use the finally block where appropriate.
For example, closing database connections, or file handles, etc.
HTH
Harv

.NET and C# Exceptions. What is it reasonable to catch

Disclaimer, I'm from a Java background. I don't do much C#. There's a great deal of transfer between the two worlds, but of course there are differences and one is in the way Exceptions tend to be thought about.
I recently answered a C# question suggesting that under some circstances it's reasonable to do this:
try {
some work
} catch (Exeption e) {
commonExceptionHandler();
}
(The reasons why are immaterial). I got a response that I don't quite understand:
until .NET 4.0, it's very bad to catch
Exception. It means you catch various
low-level fatal errors and so disguise
bugs. It also means that in the event
of some kind of corruption that
triggers such an exception, any open
finally blocks on the stack will be
executed, so even if the
callExceptionReporter fuunction tries
to log and quit, it may not even get
to that point (the finally blocks may
throw again, or cause more corruption,
or delete something important from the
disk or database).
May I'm more confused than I realise, but I don't agree with some of that. Please would other folks comment.
I understand that there are many low level Exceptions we don't want to swallow. My commonExceptionHandler() function could reasonably rethrow those. This seems consistent with this answer to a related question. Which does say "Depending on your context it can be acceptable to use catch(...), providing the exception is re-thrown." So I conclude using catch (Exception ) is not always evil, silently swallowing certain exceptions is.
The phrase "Until .NET 4 it is very bad to Catch Exception" What changes in .NET 4? IS this a reference to AggregateException, which may give us some new things to do with exceptions we catch, but I don't think changes the fundamental "don't swallow" rule.
The next phrase really bothers be. Can this be right?
It also means that in the event
of some kind of corruption that
triggers such an exception, any open
finally blocks on the stack will be
executed (the finally blocks may
throw again, or cause more corruption,
or delete something important from the
disk or database)
My understanding is that if some low level code had
lowLevelMethod() {
try {
lowestLevelMethod();
} finally {
some really important stuff
}
}
and in my code I call lowLevel();
try {
lowLevel()
} catch (Exception e) {
exception handling and maybe rethrowing
}
Whether or not I catch Exception this has no effect whatever on the excution of the finally block. By the time we leave lowLevelMethod() the finally has already run. If the finally is going to do any of the bad things, such as corrupt my disk, then it will do so. My catching the Exception made no difference. If It reaches my Exception block I need to do the right thing, but I can't be the cause of dmis-executing finallys
For the question #2:
The author meant "Corrupted State Exceptions". They will be introduced in .NET 4.0 (CLR team announced this at PDC 2008 in this talk).
Corrupted state exceptions cannot be caught by normal catch block. Examples: Access violation, Invalid Memory.
But you might want to catch these exceptions:
In main() – write to log, exit, turn off addin
Very rare cases when you know that code throws exception like this (e.g. some cases with interop with native code)
To do this you should put attribute [HandleProcessCorruptedStateException] at the method where you want to catch CorruptedStateException.
To read more about these exceptions please see this MSDN article.
As a general rule you shouldn't catch exceptions unless:
You have a specific exception that you can handle and do something about. However in this case you should always check whether you shouldn't be trying to account for and avoid the exception in the first place.
You are at the top level of an application (for instance the UI) and do not want the default behaviour to be presented to the user. For instance you might want an error dialog with a "please send us your logs" style message.
You re-throw the exception after dealing with it somehow, for instance if you roll back a DB transaction.
Your finally blocks always execute. Your code sample is correct - the low level method should just have try and finally. For instance an unmanaged call might know that it needs to dispose of the unmanaged resource, but this wouldn't be exposed to .Net methods calling it. That call should get rid of the unmanaged resource in its finally block, and calling managed methods can handle exceptions or just pass them on up.
If there's something in an exception that you need to handle you should re-throw the exception, for instance:
try {
conn.BeginTransaction();
//do stuff
conn.CommitTransaction();
}
catch (Exception) {
conn.RollbackTransaction(); //required action on any exception
throw; //re-throw, don't wrap a new ex to keep the stack trace
}
finally {
conn.Dispose(); //always dispose of the resource
}
My motto is handle what you can (or need to) and let any other exceptions bubble up and catch them in an UnhandledException event.
You are correct tho, a finally block is always called (even in the event of an exception being raised in the try section) before you exit the method. So whether you want to the catch the exception on the out method or not is entirely up to you.....this should not affect the finally block being called.
Just to your third question:
If you have
nastyLowLevel() {
doSomethingWhichMayCorruptSomethingAndThrowsException();
}
MyEvilCatcher() {
try {
nastyLowLevel();
} catch (Exception e) {
MyExceptionHandler(e);
}
}
WiseCatcher() {
try {
MyEvilCatcher();
} catch (LowLevelException e) {
DoSomethingWiseSoFinnalyDontRuinAnything();
} finally {
DoSomethingWhichAssumesLowLevelWentOk();
}
}
I think the response you asked about just meant that some low level methods could use exceptions to inform some outer method that special care has to be taken. If you forget about this exceptions in your catch-all-handler and don't rethrow them, something might go wrong.
Generally, I prefer thinking carefully about which exceptions can possibly be thrown and catch them explicitely. I only use "generic handler" at the very outer level in production environments in order to log unexpected exception and present them to the customer in an well-formatted manner (including a hint to send us the log file.)
I think the quoted response is wrong (or maybe meant 2.0 instead of 4.0)? It sounds kinda bogus to me.

Is this a bad practice to catch a non-specific exception such as System.Exception? Why?

I am currently doing a code review and the following code made me jump. I see multiple issues with this code. Do you agree with me? If so, how do I explain to my colleague that this is wrong (stubborn type...)?
Catch a generic exception (Exception ex)
The use of "if (ex is something)" instead of having another catch block
We eat SoapException, HttpException and WebException. But if the Web Service failed, there not much to do.
Code:
try
{
// Call to a WebService
}
catch (Exception ex)
{
if (ex is SoapException || ex is HttpException || ex is WebException)
{
// Log Error and eat it.
}
else
{
throw;
}
}
The mantra is:
You should only catch exceptions if
you can properly handle them
Thus:
You should not catch general
exceptions.
In your case, yes, you should just catch those exceptions and do something helpful (probably not just eat them--you could throw after you log them).
Your coder is using throw (not throw ex) which is good.
This is how you can catch multiple, specific exceptions:
try
{
// Call to a WebService
}
catch (SoapException ex)
{
// Log Error and eat it
}
catch (HttpException ex)
{
// Log Error and eat it
}
catch (WebException ex)
{
// Log Error and eat it
}
This is pretty much equivalent to what your code does. Your dev probably did it that way to avoid duplicating the "log error and eat it" blocks.
I am currently doing a code review and the following code made me jump. I see multiple issues with this code. Do you agree with me?
Not totally, see below.
Catch a generic exception (Exception ex)
In general, catching a generic exception is actually ok as long as you rethrow it (with throw;) when you come to the conclusion that you can't handle it. The code does that, so no immediate problem here.
The use of "if (ex is something)" instead of having another catch block
The net effect of the catch block is that only SoapException, HttpException, etc. are actually handled and all other exceptions are propagated up the call stack. I guess functionality-wise this is what the code is supposed to do, so there's no problem here either.
However, from a aesthetics & readability POV I would prefer multiple catch blocks to the "if (ex is SoapException || ..)". Once you refactor the common handling code into a method, the multiple catch blocks are only slightly more typing and are easier to read for most developers. Also, the final throw is easily overlooked.
We eat SoapException, HttpException and WebException. But if the Web Service failed, there not much to do.
Here possibly lurks the biggest problem of the code, but it's hard to give advice without knowing more about the nature of the application. If the web service call is doing something that you depend on later then it's probably wrong to just log & eat the exceptions. Typically, you let the exception propagate to the caller (usually after wrapping it into e.g. a XyzWebServiceDownException), maybe even after retrying the webservice call a few times (to be more robust when there are spurious network issues).
The problem with catching and re-throwing the same exception is that, although .NET does its best to keep the stack trace intact, it always ends up getting modified which can make tracking down where the exception actually came from more difficult (e.g. the exception line number will likely appear to be the line of the re-throw statement rather than the line where the exception was originally raised). There's a whole load more information about the difference between catch/rethrow, filtering, and not catching here.
When there is duplicate logic like this, what you really need is an exception filter so you only catch the exception types you're interested in. VB.NET has this functionality, but unfortunately C# doesn't. A hypothetical syntax might look like:
try
{
// Call to a WebService
}
catch (Exception ex) if (ex is SoapException || ex is HttpException || /* etc. */)
{
// Log Error and eat it
}
As you can't do this though, what I tend to do instead is use a lambda expression for the common code (you could use a delegate in C# 2.0), e.g.
Action<Exception> logAndEat = ex =>
{
// Log Error and eat it
};
try
{
// Call to a WebService
}
catch (SoapException ex)
{
logAndEat(ex);
}
catch (HttpException ex)
{
logAndEat(ex);
}
catch (WebException ex)
{
logAndEat(ex);
}
I would like to add here, because the Exception handling in almost all java / C# code that I have seen is just incorrect. I.e. you end up with very difficult to debug error for ignored Exceptions, or, equally bad, you get an obscure exception which tells you nothing, because blindly following the "catching(Exception) is bad" and things are just worse.
First, understand that an exception is a way to facilitate the returning of error information across code layers. Now, mistake 1: a layer is not just a stack frame, a layer is code which has a well defined responsibility. If you just coded interfaces and impls just because, well you have better things to fix.
If the layers are well designed and have specific responsibilities, then the information of the error has different meaning as it bubbles up. <-this is the key on what to do, there is no universal rule.
So, this means that when an Exception occurs you have 2 options, but you need to understand where in the layer you are:
A) If you are in the middle of a layer, and you are just an internal, normally private, helper function and something goes bad: DONT WORRY, let the caller receive the exception. Its perfectly OK because you have no business context and
1) You are not ignoring the error and
2) The caller is part of your layer and should have known this can happen, but you might not now the context to handle it down below.
or ...
B) You are the top boundary of the layer, the facade to the internals. Then if you get an exception the default shall be to CATCH ALL and stop any specific exceptions from crossing to the upper layer which will make no sense to the caller, or even worse, you might change and the caller will have a dependency to an implementation detail and both will break.
The strength of an application is the decoupling level between the layers. Here you will stop everything as a general rule and rethrow the error with a generic exception translating the information to a more meaningful error for the upper layer.
RULE: All entry points to a layer shall be protected with CATCH ALL and all errors translated or handled. Now this 'handeled' happens only 1% of the time, mostly you just need (or can) return the error in a correct abstraction.
No I am sure this is very difficult to understand. real Example ->
I have a package that runs some simulations. These simulations are in text scripts. there is a package that compiles these scripts and there is a generic utils package that just reads text files and, of course, the base java RTL. The UML dependency is->
Simulator->Compiler->utilsTextLoader->Java File
1) If something breaks in the utils loader inside one private and I get a FileNotFound, Permissions or what ever, well just let it pass. There is nothing else you can do.
2) At the boundary, in the utilsTextLoader function initially called you will follow the above rule and CATCH_ALL. The compiler does not care on what happen, it just needs to now whether the file was loaded or not. So in the catch, re throw a new exception and translate the FileNotFound or whatever to "Could not read file XXXX".
3) The compiler will now know that the source was not loaded. Thats ALL it needs to know. So if I later I change utilsTestLoader to load from network the compiler will not change. If you let go FileNotFound and later change you will impact compiler for nothing.
4) The cycle repeats: The actual function that called the lower layer for the file will do nothing upon getting the exception. So it lets it go up.
5) As the exception gets to the layer between simulator and compiler the compiler again CATCHES_ALL, hiding any detail and just throws a more specific error: "Could not compile script XXX"
6) Finally repeat the cycle one more time, the simulator function that called the compiler just lets go.
7) The finally boundary is to the user. The user is a LAYER and all applies. The main has a try that catches_ALL and finally just makes a nice dialog box or page and "throws" a translated error to the user.
So the user sees.
Simulator: Fatal error could not start simulator
-Compiler: Could not compile script FOO1
--TextLoader: Could not read file foo1.scp
---trl: FileNotFound
Compare to:
a) Compiler: NullPointer Exception <-common case and a lost night debugging a file name typo
b) Loader: File not found <- Did I mention that loader loads hundreds of scripts ??
or
c) Nothing happens because all was ignored!!!
Of course this assumes that on every rethrow you didn't forget to set the cause exception.
Well my 2cts. This simple rules have saved my life many times...
-Ale
Sometimes that is to only way to handle "catch every exception" scenarios, without actually catching every exception.
I think sometimes, say, lowlevel framework / runtime code needs to make sure that no exception is ever escaping. Unfortunately, there is also no way the framework code can know which exceptions are raised by the code executed by the thread.
In that case a possible catch block could look like this:
try
{
// User code called here
}
catch (Exception ex)
{
if (ExceptionIsFatal(ex))
throw;
Log(ex);
}
There are three important points here, however:
This isn't something for every situation. In code reviews we are very picky about places where this is actually neccessary and thus allowed.
The ExceptionIsFatal() method assures that we don't eat exceptions which should never be swallowed (ExecutionEngineException, OutOfMemoryException, ThreadAbortException, etc.)
What is swallowed is carefully logged (event-log, log4net, YMMV)
Typically, I'm all for the practice of letting uncaught exceptions simply "crash" the application by terminating the CLR. However, especially in server applications, this is sometimes not sensible. If one thread encounters a problem which is deemed non-fatal, there is no reason in ripping the whole process down, killing off all other running requests (WCF, for example, handles some cases this way).
You should usually still catch generic exceptions in a global handler (which is the perfect place to log unexpected Exceptions), but otherwise as said before, you should only catch specific exception types in other places if you plan to do something with them. The catch blocks should look for those exception types explicitly, not as the code you posted does.
I don't think this is such a bad thing in this case, but I also do something similar in my code with exceptions that can be safely ignored being caught and the rest being re-thrown. As noted by Michael's response, having each catch being a separate block could cause some readability issues which are prevented by going this route.
In regards to pointing this out to your colleague, I think you would have a hard time convincing them that this is the wrong way of doing things - even more so if they are stubborn - because of the potential readability issues with doing things the other way. Since this version is still throwing the generic exception's that can't be handled it is in keeping with the spirit of the practice. However, if the code was in line with the following:
try
{
// Do some work
}
catch (Exception ex)
{
if (ex is SoapException)
{
// SoapException specific recovery actions
}
else if (ex is HttpException)
{
// HttpException specific recovery actions
}
else if (ex is WebException)
{
// WebException specific recoery actions
}
else
{
throw;
}
}
Then I think you would have a bit more of a reason to be concerned as there is no point in doing work for a specific exception by checking for it in a general exception block.
the princeple is only to catch the exception you can handle.
such as, if you know how to deal with findnotfound, you catch the filenotfoundexception, otherwiese, do NOT catch it and let it be thrown to the upper layer.

Should I catch exceptions only to log them?

Should I catch exceptions for logging purposes?
public foo(..)
{
try
{
...
} catch (Exception ex) {
Logger.Error(ex);
throw;
}
}
If I have this in place in each of my layers (DataAccess, Business and WebService) it means the exception is logged several times.
Does it make sense to do so if my layers are in separate projects and only the public interfaces have try/catch in them?
Why? Why not? Is there a different approach I could use?
Definitely not. You should find the correct place to handle the exception (actually do something, like catch-and-not-rethrow), and then log it. You can and should include the entire stack trace of course, but following your suggestion would litter the code with try-catch blocks.
Unless you are going to change the exception, you should only log at the level where you are going to handle the error and not rethrow it. Otherwise your log just has a bunch of "noise", 3 or more of the same message logged, once at each layer.
My best practice is:
Only try/catch in public methods (in general; obviously if you are trapping for a specific error you would check for it there)
Only log in the UI layer right before suppressing the error and redirecting to an error page/form.
The general rule of thumb is that you only catch an exception if you can actually do something about it. So at the Business or Data layer, you would only catch the exception in situation's like this:
try
{
this.Persist(trans);
}
catch(Exception ex)
{
trans.Rollback();
throw;
}
My Business/Data Layer attempts to save the data - if an exception is generated, any transactions are rolled back and the exception is sent to the UI layer.
At the UI layer, you can implement a common exception handler:
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
Which then handles all exceptions. It might log the exception and then display a user friendly response:
static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
LogException(e.Exception);
}
static void LogException(Exception ex)
{
YYYExceptionHandling.HandleException(ex,
YYYExceptionHandling.ExceptionPolicyType.YYY_Policy,
YYYExceptionHandling.ExceptionPriority.Medium,
"An error has occurred, please contact Administrator");
}
In the actual UI code, you can catch individual exception's if you are going to do something different - such as display a different friendly message or modify the screen, etc.
Also, just as a reminder, always try to handle errors - for example divide by 0 - rather than throw an exception.
It's good practice is to translate the exceptions. Don't just log them. If you want to know the specific reason an exception was thrown, throw specific exceptions:
public void connect() throws ConnectionException {
try {
File conf = new File("blabla");
...
} catch (FileNotFoundException ex) {
LOGGER.error("log message", ex);
throw new ConnectionException("The configuration file was not found", ex);
}
}
Use your own exceptions to wrap inbuild exception. This way you can distinct between known and unknown errors when catching exception. This is usefull if you have a method that calls other methods that are likely throwing excpetions to react upon expected and unexpected failures
you may want to lookup standard exception handling styles, but my understanding is this: handle exceptions at the level where you can add extra detail to the exception, or at the level where you will present the exception to the user.
in your example you are doing nothing but catching the exception, logging it, and throwing it again.. why not just catch it at the highest level with one try/catch instead of inside every method if all you are doing is logging it?
i would only handle it at that tier if you were going to add some useful information to the exception before throwing it again - wrap the exception in a new exception you create that has useful information beyond the low level exception text which usually means little to anyone without some context..
Sometimes you need to log data which is not available where the exception is handled. In that case, it is appropriate to log just to get that information out.
For example (Java pseudocode):
public void methodWithDynamicallyGeneratedSQL() throws SQLException {
String sql = ...; // Generate some SQL
try {
... // Try running the query
}
catch (SQLException ex) {
// Don't bother to log the stack trace, that will
// be printed when the exception is handled for real
logger.error(ex.toString()+"For SQL: '"+sql+"'");
throw; // Handle the exception long after the SQL is gone
}
}
This is similar to retroactive logging (my terminology), where you buffer a log of events but don't write them unless there's a trigger event, such as an exception being thrown.
If you're required to log all exceptions, then it's a fantastic idea. That said, logging all exceptions without another reason isn't such a good idea.
You may want to log at the highest level, which is usually your UI or web service code. Logging multiple times is sort of a waste. Also, you want to know the whole story when you are looking at the log.
In one of our applications, all of our pages are derived from a BasePage object, and this object handles the exception handling and error logging.
If that's the only thing it does, i think is better to remove the try/catch's from those classes and let the exception be raised to the class that is responsible on handling them. That way you get only one log per exception giving you more clear logs and even you can log the stacktrace so you wont miss from where the exception was originated.
My method is to log the exceptions only in the handler. The 'real' handler so to speak. Otherwise the log will be very hard to read and the code less structured.
It depends on the Exception: if this actually should not happen, I definitely would log it. On the other way: if you expect this Exception you should think about the design of the application.
Either way: you should at least try to specify the Exception you want to rethrow, catch or log.
public foo(..)
{
try
{
...
}
catch (NullReferenceException ex) {
DoSmth(e);
}
catch (ArgumentExcetion ex) {
DoSmth(e);
}
catch (Exception ex) {
DoSmth(e);
}
}
You will want to log at a tier boundary. For example, if your business tier can be deployed on a physically separate machine in an n-tier application, then it makes sense to log and throw the error in this way.
In this way you have a log of exceptions on the server and don't need to go poking around client machines to find out what happened.
I use this pattern in business tiers of applications that use Remoting or ASMX web services. With WCF you can intercept and log an exception using an IErrorHandler attached to your ChannelDispatcher (another subject entirely) - so you don't need the try/catch/throw pattern.
You need to develop a strategy for handling exceptions. I don't recommend the catch and rethrow. In addition to the superfluous log entries it makes the code harder to read.
Consider writing to the log in the constructor for the exception. This reserves the try/catch for exceptions that you want to recover from; making the code easier to read. To deal with unexpected or unrecoverable exceptions, you may want a try/catch near the outermost layer of the program to log diagnostic information.
BTW, if this is C++ your catch block is creating a copy of the exception object which can be a potential source of additional problems. Try catching a reference to the exception type:
catch (const Exception& ex) { ... }
This Software Engineering Radio podcast is a very good reference for best practices in error handling. There are actually 2 lectures.
It's bad practice in general, unless you need to log for very specific reasons.
With respect in general log exception, it should be handled in root exception handler.

Categories