I've been given a task to create a general exception handling code snippet, I have a couple of questions:
Is it a good idea? General exception handling leads to generalized messages as to what's breaking, making tracking hard.Leading to :
What should I include in the snippet? I figure less is more here but adding a log seems to be a good idea because I don't think the exception messages are going to be very specific.
I wouldn't say it's a good idea, no. I tend to have relatively few exception handlers in my code. They're typically there to:
Occasionally convert an exception of one type into another (although that's rarer in C# than in Java; whether it's a good thing or not is a different discussion)
Catch errors at the root of the stack for a particular request / user action / whatever, usually just logging the result
Handle bone-headed APIs which throw exceptions in non-exceptional situations
None of these takes long to write, and none of them comes up so often that it's worth having a common snippet.
Having a set of documented conventions around exception handling - with a discussion of the design in the same document - is a good idea though.
it's better to add specific exception handling and including logs... But, you can add the general exception as well, to catch all unknown exceptions.
Stack traces (to those who can read them) are 90% of what you need. Including the parameters passed into the erroring method will also GREATLY help in debugging. If this is logging to a database, please be careful about logging sensitive pieces of data (PII or PHI).
If this is a web application, I would recommend saving a snapshot of the session as well, this can also help greatly in debugging.
I would recommend you to use Code Contracts and AOP tools like PostSharp. They both provide great possibilities to debug and error-handle your code.
I always use these guidelines as what should be handled by exceptions and what should not. Also, it's hard to get exceptions right.
What I usually end up with is code that has few, if any specific exception handlers, and a global catch-all handler, that just logs the exception (including the stack trace).
That said, when you do use local exception handling, and if the default try.snippet is lacking, something like this might work (just the code included, the rest of the .snippet file is a bit obvious):
try
{
$selected$
}
catch ($caughtExceptionType$Exception ex)
{
$end$
Logger.Error("$message", ex);
//throw new $customExceptionType$Exception("$message", ex);
}
I think that a general exception handler strategy is only applicable at the entry points in the code that you'd like to treat unhandled exceptions. Maybe in a Main method for single-threaded application code or in the AppDomain.UnhandledException event.
Then, the strategy to use is highly application specific. Maybe you have a central log to add the information to, or a message queue that will trigger further processing (e.g., insert in a database and inform an administrator).
Related
Recently I have used Global exception handling in my code and I came to know that with this all exceptions can be handled. Previously I was using try-catch at each controller and now I have removed all the try-catch from controller because of Global exception as it can handle all types of exception.
So I doubt that, is it a good practice to remove all the exception handling I have previously used in the controller for Global Exception handling or should use both Global, as well as try-catch at the controller.
And if try-catch is required, is it necessary that all the exceptions are to be handled at the controller level.
My current working stack is - .Net Core.
The question is too broad to give a full answer but, let me give my opinion on this matter.
try-catch-finally blocks are not used to handle unhandled exceptions. Naturally the cases that you never thought of will be unhandled and you should not keep them silent but you should allow them to express themselves for you to think about them. Handled exceptions though are the cases that are not at the hand of the programmer but he/she has thought about them. For example user input is string instead of number.
If it's the case that you thought but is in your control always check with ifs. For example if something can be null. Try-catch is really costly and no logic should be handled in them.
Using a global exception handler on the other hand is the exact opossite. It is not to wrap all thought cases and show a single response to user. You should log unknown exceptions to come back and think about why they happened and in the mean time say that you are sorry to user. :)
Should application logging code always be in catch block?
Is it better for instance to check is object null in try block and if so log the exception or catch nullreference exception and log error(warning)
It will always* be a better practice to prevent an exception in the first place than to handle one after the fact.
If a null reference is a real possibility, the code should already test for and appropriately handle this.
Logging should be as disconnected from exception handling as possible. Really, you need to log as much as possible and then let your application logger decide what's actually important. (Use error levels - information, warning, error) So yes, your catch blocks should log, but that should definitely not be the only place you do logging.
*I'm sure there's some edge-case scenario where this isn't true, but it's quite rare.
It is always good to have logs which will help you to understand what is going on, how application behaves, to do proper tracking, monitoring and etc...but where to have it I think it depends from your application and context. For sure the exception details must be logged so you can check what is happening, but to log in catch block in finally block or somewhere else it depends from your code.
Always is a strong word, Logging code should be where needed. In most cases there are categories of logging.
**INFO**: General application information
**DEBUG**: Information that may be helpful if trying to debug using the log.
**ERROR**: Error information.
I'm sure there are other categories however as you can see, in the case of these 3, ERROR logging will probably only be in the catch block where as the other 2 can really be anywhere.
It's better doing so within the catch block, even if on the basis of readability alone. It's always better to separate error-handling from your other code.
I think logging is a cross-cutting concern, so I'd put it in an aspect. The more catch blocks you have, the more logging code you have to write. If you can weave advice into exceptions you can write that logging code once and keep it in one place.
First, I'm already familiar with the simple exception handling syntax but I'm asking about the best place, the best time and the best way to deal with them.
I'm building an N-Layered application. so I think the DAL will sometime generate some errors to handle .. and I just learned about the SqlException class, what's the deal with that class ? I once saw a code that handles the SqlException then it handles Exception!
After knowing the practice and where I'm going to handle them, I'm planning to create a method to connect to the database and log the errors in a database so I could fix it but still I don't know what information should I collect to allow me identify the whole situation!
I thought exceptions handling was not a big deal. but every now and then I read some strange advices -that I never understood- on the questions comments but no one could answer me since it was some very old questions!
"Don't just explicitly catch
exceptions"
"the code that is used by
higher-layers in your application must
always only throw exceptions and never
worry about how to deal with them."
EDIT
What about Page_Error event and Application_Error .. I saw that they are a good practice for handling errors
Exception handling is a big deal, and it's not simple to design a good strategy for that.
First of all, some general rules:
Exceptions occur when the running code is completely unable to go ahead, so maybe it tried to handle some internal exceptions but ultimately failed. Think about TCP connection: if a damaged packet arrives, it's an exception, but TCP protocol can handle it. If too many are damaged, an I/O or socket exception is thrown
Exceptions can not always be handled. In almost all cases, when you get an exception from underlying layers you are unable to run corrective code. If your application depends on a DB and that is offline, when you get the exception about it you can only display an error message
Exceptions can be unexpected, and can reveal design or implementation flaws. For example, an implementation flaw can be the situation in which you have a redundant DB but when you fail to connect to frist mirror you don't try with the second
For the third point, it's important to log exceptions and periodically analyse logs to find any weird situation. So, let's begin with the concrete answer.
First of all
think about "handling" the exception. When you write every single code line, think about the possible problems that may prevent it from completing, and think about the possible corrective actions. if any are possible. An error message is not a good handling way, it's the latest strategy.
Don't start to write try-catch(Exception), but prefer specific exceptions. If you need to parse strings to numbers etc, then expect FormatException, if you need to cast from Object to your type expect InvalidCastException
When you write lower-level layers
don't hesitate to throw exceptions!! Don't do like many folks do, ie. return null or use (like ANSI C) a boolean return value and reference parameters. Exceptions are there for that. If you can handle an exception (ie. you don't find a local file but you know you have a remote backup, so handle FileNotFoundException by calling the remote mirror, but if you can't still connect then ultimately throw) then do it and try to resume computation, but if you cannot then throw. And don't forget to throw the inner exception, if present, because it is helpful for logging in the highest layer.
Basically, you can still decide to throw an exception on your own even if you don't catch any! And this is highly recommended especially when function parameters are invalid!
Another good option is to still log in the underlying layers. You actually want to log no matter an exception occurs.
When you log
remember to give an adequate severity to the messages. If you find via code that your DB is offline, that's not an unexpected exception. Still log it as an error, but don't worry about code bugs when you investigate the logs. Instead, if you catch an exception that your code is unable to recognize (a NullReferenceException is a classic example) then log with highest severity, ie. fatal, to give it maximum priority!
A good strategy for ASP.NET
can surely be based upon Page.OnError method. If you have a base page class for all of the pages of your site, you should definitely override that method. In that method, you should first log your exception.
You also shouldn't abuse of try-catch(Exception) blocks, because if you don't catch an exception you can't handle with catch, you will have to handle it via OnError.
When you run such a method, don't immediately think about Server.RemoveError(). You can prefer to have a static HTML page for HTTP 500 error (that is triggered when an unhandled exception bubbles to ASP.NET runtime) that displays a courtesy message to the user.
Briefly
Don't hesitate to throw in underlying layers if anything strange occurs
As said by your advice, don't handle exceptions you are unable to handle (if you catch an exception you can't handle, rethrow it)
LOG!!!!!!!!!!!!!!!!!
Don't disclose exception details to final users on a public website, never!! By default, ASP.NET prevents that from occurring, but you could still use OnError to print stack trace
Use OnError, or Application_Error as single central point to handle all unexpected exceptions
Periodically examine logs against error/fatal messages to find issues with your code, then think about maintaining/debugging/fixing it
Take a look at elmah. It's a logger for asp.net. Renders all errors on a nice summary page.
http://code.google.com/p/elmah/
The best way to handle exceptions is in the specific layer they apply to. If it is a constraint volation, for example, 2 users with the same name, you should let that bubble up to the UI and alert the user.
Same goes with any business rule violations. Those should bubble up to the UI so the end user knows what went wrong.
A SQL Connectivity error is best handled in the DAL...etc..
The how/when/where to catch exceptions may depend on what your trying to do exactly, its difficult to give an exact catch all always correct answer.
As to your specific questions,
I just learned about the SqlException
class, what's the deal with that class
? I once saw a code that handles the
SqlException then it handles
Exception!
Its good practice to handle the specific exception you believe may occur, if your not sure what type this exception is you can just 'Exception', if you want something specific to occur on a 'SQLException' and something else to happen with an 'Exception' then there is certainly nothing wrong with writing code that handles both.
"Don't just explicitly catch
exceptions"
I believe this is refering to code like this
try
{
int i = 1/0;
}
catch(Exception e)
{
//do nothing
}
This exception will be caught but you'll never know it happened, hence this is not a good idea, and the person using the code will be scratching their head as to whats going on.
I think what you are asking here is a Error/Exception Handling Strategy for any application.
I think it includes:
Where - All places where you think an exception can occur or which need more monitoring like DB calls, External Service Calls, Use of Arrays, User Input Parsing, Type Casting and so on...
How - All you high level layers should throw the exception and it should be captured at the entry point and processed to understand the root cause. Usually you do this in Application_Error() where you catch the exception and log it for troubleshooting. How you log an exception is upto you. A Log File or DB driven log is an option based on your requirements and available resources.
IMO apart from extremely rare circumstances I only ever use exception handling for I/O related code where there are interactions with services and file systems whose functionality and maintenance is beyond the control of my applications.
I have always considered the use try/catch statements to manipulate the logic (flow-of-control) in a program in the same way if/else statement work to be extremely bad practice. Most common exceptions can be avoided if you use the tools at hand correctly.
I've found myself doing too much error handling with try\catch statements and getting my code ugly with that. You guys have any technique or framework to make this more elegant? (In c# windows forms or asp.net).
You need to read up on structured exception handling. If you're using as many exception handlers as it sounds then you're doing it wrong.
Exception handling isn't like checking return values. You are supposed to handle some exceptions in limited, key spots in your code not all over the place. Remeber that exceptions "bubble up" the call stack!
Here is a good and well-reviewed CodeProject article on exception best practices.
Java land had pretty the same problem. You just look at method and you can't at a first glance understand what it is doing, because all you see is try/catch blocks. Take a 30-40 line method and throw away all try statements and catch blocks and you might end up with 5-6 lines of pure application logic. This isn't such a big problem with C# as it has unchecked exceptions, but it gets really ugly in Java code. The funny thing is the try/catch blocks were intended to solve the very same problem in the first place. Back then it was caused by errno/errstr madness.
What the Java guys usually do is based on how do you typically handle exception. Most of the time you can't really do anything to correct the problem. You just notify the user that whatever he was trying to do didn't work, put back application in a certain state and maybe log and exception with complete stacktrace to log file.
Since you handle all the exceptions like this, the solution is to have a catch-all exception handler, which sits on top of application stack and catches all exceptions that are thrown and propagated up the stack. With ASP.NET you might use something like this:
http://www.developer.com/net/asp/article.php/961301/Global-Exception-Handling-with-ASPNET.htm
At the same time you are free to override that global handler by placing try/catch block in your code, where you feel something can be done, to correct the problem.
Just adding a Try Catch does not solve the problem. This topic a too big to handle as one question. You need to do some reading.
http://msdn.microsoft.com/en-us/library/8ey5ey87%28VS.71%29.aspx
http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx
Also FXCop, and VS Team System will warn you on some design issues.
Such heavy reliance on exception handling (in any language) does suggest that the mechanism is being misused. I always understood that exception handling was designed to trap the truly exceptional, unforeseeable event. It is not designed to handle (for instance) invalid data entry by a user - this is normal operation and your design and application coding must deal with such normal processing.
http://msdn.microsoft.com/en-us/library/ff664698(v=PandP.50).aspx
Check out Microsoft's Exception Handling Application Block. It has an intial learning curve, but is good stuff once you get it figured out.
My question actually comes in two parts hence the ambiguous title.
Part One
As far as I'm aware, you should never swallow an exception. Not even logging it and forgetting about. In general cases, I try to solve an exception and retry the code - for example, let's say I get a FileNotFound exception.
I prompt the user to check the file exists and try again, offering another file chooser dialog and hoping for the best. Failing attempting to solve the problem I end up notifying the user and logging the exception. I've been told that this isn't the correct thing to do in a catch block, so am I doing it right by attempting to solve the issue?
I can't think what else I should do. I suspect I'm being fed misinformation - I'm a gullable soul.
Part Two
Creating a log in my program directory to log an exception is fine I think, but again I'm being told that exceptions should be written to the windows eventlog. Is this correct? Under what circumstances should you write to the event log?
Silly questions need silly answers.
Edit:
There is no context to this question other than a general vague domain. My friend and I were blabbering about the right things to do in particular circumstances.
First off if you ever hear the word Never your ears should perk up... That is why they are called "Best Practices" and not "Rules written in Stone that you must follow..."
here is Microsoft's Exception Handling Best Practices Guide
And there are going to be plenty others...
It really boils down to you as a developer, your teams standards, your customer, etc. What do you want the application to do?
Question 1: Do you want the application to be able to continue on if an exception it thrown? Then I would "swallow" the exception.
Question 2: Is there a benefit to logging a particular exception to the event log or is it just going to bloat it with useless information, You may want to write every exception to the log during development and testing and have verbose information and then in production streamline it... I hope I have answered your question even though there really isn't an generic one...
I would say you should have some general guidelines and then if you have more specific situations then it would be a good time to re-post to this site and get some feedback from people that have tried different routes and can speak to the pros and cons.
The Code Analysis Team Blog is a great place to start on this topic. Also look at
Martin Fowler - Fail Fast
MSDN on Exception Handling
Checked vs Unchecked Exceptions
The second part of your question really depends. In many applications where you need central exception reporting, writing to the event log is a good idea. There are plenty of other cases where it would be a waste of time to do that, you'll have to use your own judgment on that.
Part One
Generally, you don't want to have exception generating behaviour in a catch block.
try
{
ExceptionThrowingMethod();
}
Catch(Exception ex)
{
//Log It
//Try Again
ExceptionThrowingMethod();
}
Clearly, the second exception will be uncaught, and you generally don't want to have try-catches nested within a catch-block.
Generally your catch block should
Log the error. Always. Even if you set it to your lowest logging level, and never read those logs.
Determine whether your current state is recoverable. (Are the right variables set or null? Did it break during a critical function, or between them?)
If you can recover, set some variables that indicate 'try-again', and allow execution to flow OUT of the catch-block. If you cannot recover, try to add some context, and then re-throw the error.
Catch blocks are for error recovery, not for regular execution. So, even through FileNotFound is an exceptional occurrence, prompting the user to try and locate their file is not, and so it should happen in its own try-catch (or loop back to the initial one).
Part Two
Generally, I would prefer writing logs to their own directory, because that way I know exactly where they are, and I also know that everything in the log is relevant. If your application is a critical application, (I.E. a service that needs to be running for a framework to work) then you might consider logging to the eventviewer. There's also the everybody wins method of logging to both. You could have thorough logs in your program directory, and log any critical errors to your event viewer.
Without knowing what reason you were given to log to the event viewer, I can't tell whether or not it's good advice.
Here are some best-practices for exception handling.
Best practices for exception management in Java or C#
I found this to answer part two of my question and it seems from a bit of further research that logging exceptions to the event log isn't a mysterious and dark practice. Thanks for your help everyone.