Exception handling within an Exception in C# - c#

i know this could be a little weird but a doubt is a doubt afterall...
what would happen in the following situation...
private void SendMail()
{
try
{
//i try to send a mail and it throws an exception
}
catch(Exception ex)
{
//so i will handle that exception over here
//and since an exception occurred while sending a mail
//i will log an event with the eventlog
//All i want to know is what if an exception occurs here
//while writing the error log, how should i handle it??
}
}
Thank you.

I would personally wrap the call to write to event log with another try\catch statement.
However, ultimately it depends on what your specification is. If it is critical to the system that the failure is written to the event log then you should allow it to be thrown. However, based on your example, I doubt this is what you want to do.

You can simply catch errors in the error logging method. However I wouldn't personally do that, as broken error logging is a sign your application can't function at all.
private void SendMail()
{
try
{
//i try to send a mail and it throws an exception
}
catch(Exception ex)
{
WriteToLog();
}
}
private void WriteToLog()
{
try
{
// Write to the Log
}
catch(Exception ex)
{
// Error Will Robinson
// You should probably make this error catching specialized instead of pokeman error handling
}
}

Each exception is caught only when inside a try-catch block. You could nest try-catch but is generally not a good idea.

You could add a try-catch block in your catch block as well.

Considering the kind of exceptions when writing to a file (rights, disk space...) I would advice not to handle it in here. If it fails the first time, there's good chance you won't be able to write to the event log that it's not possible to write in the event log...
Let it bubble up and be handled by an upper level try/catch.

Chris S. has the best answer. Placing a try-catch block inside a catch block is very rarely a good idea. and in your case it will just convolute your code. If you check to see if you were successful in writing to your log file here, you will have to do it in every place where you try to write into your log file. You can easily avoid this unnecessary code duplication by having all your individual modules be self contained when it comes to notifying/handling of error conditions within these modules. When sending your mail fails you perform the proper actions inside your catch block to handle this exceptional condition like:
disposing of the contents of your mail object
making sure your socket is closed
writing an entry into your log file to note the error
Inside your catch block just call whatever API you have defined to writing a log entry into your logfile and forget about about the rest. Inside your logging API is where you should handle any logging related exceptional cases (the disk is full, no permission to write to file, file not found, etc...). Your mailing module does not need to know if the logging was successful or not, that responsibility should be delegated to the logging module.

I personally handle this situation using a simple extension method.
public static class MyExtentions
{
public static void LogToErrorFile(this Exception exception)
{
try
{
System.IO.File.AppendAllText(System.IO.Path.Combine(Application.StartupPath, "error_log.txt"),
String.Format("{0}\tProgram Error: {1}\n", DateTime.Now, exception.ToString()));
}
catch
{
// Handle however you wish
}
}
}
The usage is simple:
try
{
...
}
catch(Exception ex)
{
ex.LogToErrorFile();
}
You can then handle the caught exception inside the extension method however you want, or simply don't catch it and let it bubble up to the top. I've found this design to be a simple, reproducible way to handle exceptions throughout the application.

Firstly I would say don't catch "Exception" in catch block. You could instead, for mailing, check for all validity and then catch specific exception(SmtpException, ) that you can do something about(and informing user with a friendly message). Throwing exception from your code and informing the UI about is not a bad idea. If your methods accepts inputs with certain specification and if they are not met, your method should/can throw error and inform user about it.
For exceptions that have no control over, use global handling exception, like Application_Error for web.
Getting Better Information on Unhandled Exceptions Peter Bromberg explains this better.
Also for any privildged resource you are accessing, like eventlogs, make sure you assembly has access to it.
Useful links Build a Really Useful ASP.NET Exception Engine By Peter A. Bromberg
and
Documenting Exceptional Developers By Peter A. Bromberg
For web application look into
Health monitoring
Exception logging
One more thing, if your application goes wrong/ throws error that can't handle( at all) its better to let it go down gracefully and not continue. Application in unstable state is not good idea.

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 ;)

modifying existing program to handle exceptions better

I'm working on an existing C# program that queries and makes changes to various resources outside of the program and computer that the program is run on. The program works on most computers but randomly fails on random computers every so often. When this happens we have no feedback as to why other than what the user tells us about the exception that was thrown up on the screen that they may or may not have already cleared. Even if they leave it up on the screen for us it provides little to no useful information to us. I have since modified the program to log particular events and gathered information to a text file that I can use to approximate where the program stopped. This is at least a start but from reading many threads on stackoverflow.com as well as other forums I know that the program needs to at least make an attempt to handle the specific exceptions that could come up when querying and modifying LDAP, DS, DNS, SQL and so on.
Currently there is just big try blocks surrounding all of the to do code with just one catch block at the end of each.
private void method_name()
{
try
{
//many lines of to do code calling many other methods
}
catch (exception ex)
{
MessageBox.Show("An Error has occurred in method_name() :" + ex.Message);
}
My first thought was to nest more specific try/catch blocks within the larger try blocks but I keep running into problems with variables becoming unreachable in different contexts. for example
try
{
LdapConnection ldapConn = new LdapConnection();
ldapConn.Connect(details of connection);
ldapConn.Bind(details of bind statement);
LdapSearchQueue queue = ldapConn.Search(search criteria and such);
LdapMessage message;
}
catch (somesortofexception ex)
{
//do something sensible about it
}
while ((message = queue.getResponse()) != null)
{
//do things with message
}
ldapConn.Disconnect();
the problem being that message and queue are unreachable outside of the try block. This is just one example of something done withing the "//many lines of to do code calling many other methods" that I'm trying to work with.
So here are my questions:
Would it be better to try and make the try block bigger in the above example to include the while loop and ldap disconnect or to just leave the big try loop, make a list of things that happen during that and create many catch blocks at the end to catch specific exceptions? I feel like putting in the smaller try blocks around specific code is the way to go based on what I've read on this site.
Should I use the smaller try blocks like I've been trying to implement, would be be okay to just use a catch block that catches any exception raised within that small snippet of code and log it to my log file or should I try and catch specific exceptions? I don't really have anything different I can do with those exceptions other than log them to the file anyways.
Do I need to throw the exceptions? I don't really want anything bubbling up to the user other than a message in plain english saying that something went wrong and to contact IT. Currently none of the catch blocks throw anything.
About breaking down exceptions, I would always separate the connection code from the query one.
So this would become:
LdapConnection ldapConn = new LdapConnection();
try
{
ldapConn.Connect(details of connection);
ldapConn.Bind(details of bind statement);
}
catch (somesortofexception ex)
{
//Log, send error message..
ldapConn = null;
}
if (ldapConn != null)
{
try
{
//Do what you need with your connection
}
catch (Exception ex)
{
//Log, Error....
}
finally
{
//Disconnect your ldap here
}
}
Ideally i would put all the connection code and search code in separate methods as well,
so you'll have some nicer stack trace.
About error message I would also just use some generic message and log exception specifics into some kind of file ( http://logging.apache.org/log4net/ ) is quite nice for having nicely formatted log files.
A local catch block that swallows a specific exception is fine as long as you're expecting that exception and it can be handled locally. In this case you can provide information to the user based only on what the exception contains, or you can move the variable definitions above the try block if you want to include their state in the logging and/or message.
For exceptions that you're not expecting, you should let them bubble upwards to the top of the call stack where they can be logged by a global handler before exiting the program gracefully. You don't want to potentially nail the corpse in an upright position by swallowing these exceptions.
Assuming this is a WinForms app, the setup of global handlers looks something like this:
public static void Main(string[] args)
{
// Switch-off the Windows Forms default handler for unhandled exceptions.
// NB From .NET 4 upwards, this won't work if the process state is corrupted.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Setup event handler to intercept an unhandled exception on a UI thread.
// NB The exception will still terminate the application.
// But you can show a MessageBox and/or log the exception.
Application.ThreadException +=
new ThreadExceptionEventHandler(App_UiThreadException);
// Setup event handler to intercept unhandled exception on a non-UI thread.
AppDomain.CurrentDomain.UnhandledException += new
UnhandledExceptionEventHandler(App_NonUiThreadException);
// Run the application (open main form etc).
}

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

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?

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

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