Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I am fairly new to programming and I want to know what is the proper way to structure your error handling. I have searched the internet but I have failed to find something solid about the structure of ALL your try/catch/finally statements, and how they interact with each other.
I want to present my idea of how I think I should structure my error handling in code and I would like to invite everyone check if this is correct. A big bonus would be to back it up with some other research, a common practice of some sort.
So my way of doing this would be to put try statements pretty much everywhere! (I hope I haven't raged everyone by saying this). PS - I also understand about catching different types of exceptions, I am only catching of type 'Exception' just for explanation purposes.
So for example:
I start on Main in a normal console application and then I create an
instance of A.
I then call a member function on it called AMethod1 (a.AMethod1).
A.AMethod1 creates an instance of class B and then calls BMethod1
(b.BMethod1).
This is how I would go about error handling it:
public class Program
{
static void Main (string[] args)
{
//I do not place simple code like below inside the try statement,
//because it is unnecessary and will slow the process down.
//Is this correct?
const int importantNumber = 45;
string name;
IRepositoryFactory repoFactory;
A a;
//And then I put code in 'try' where I feel it may go wrong.
try
{
a = new A();
a.AMethod1();
//Some other code
}
catch (Exception ex)
{
HandleError(ex);
}
}
}
// End of scope of Program! The functions below belong to their relative
// classes.
public void AMethod1()
{
try
{
B b = new B();
b.BMethod1();
}
catch (Exception ex)
{
//Preserving the original exception and giving more detailed feedback.
//Is this correct?
//Alternative - you still could do a normal 'throw' like in BMethod1.
throw new Exception("Something failed", ex);
}
}
public void BMethod1()
{
try
{
//some code
}
catch (Exception ex)
{
throw; //So I don't lose stack trace - Is this correct?
}
}
In summary:
I put all code in try statements (except declarations like shown in
above code)
On the client level (at the start of the call stack) I
catch the error and handle it.
Going down the call stack, I just
throw the Exception so I don't break the stack information.
I would really appreciate some resources that explains how programmers are meant to structure their error handling. Please don't forget to read the comments within the code please.
Here are some good rules of thumb:
If you are going to log the error at the level in question, use exception handling
If there is some way to solve the exception, use exception handling
Otherwise, don't add any exception handling at that level
The exception to the rules above is the UI should ALWAYS (okay, maybe not always, but I can't think of an exception to this rule right off hand) have exception handling.
In general, if you are throwing the same error, as you have in your code, it is a sign you should not handle the exception. End of story.
NOTE: When I say "at that level", I mean in the individual class or method. Unless the exception handling is adding value, don't include it. It always adds value at the user interface level, as a user does not have to see your dirty laundry, a message saying "oops, laundry day" is enough.
In my personal experience most of the exceptions are related to null object reference. I tend to follow null object pattern to avoid lots of check for null values. And also while doing a value conversion I always use tryparse so that i dont stand a chance of null issues. all in all this subject could be discussed from many perspective. if you could be a bit more specific it will be easy to answer.
stackoverflow really isn't an opinion site. It's geared heavily towards specific answers to specific questions.
But you should know that try...catch does have some overhead associated with it. Putting it "everywhere" will hurt the performance of your code.
Just use it to wrap code that is subject to unexpected errors, such as writing to disk, for example.
Also note that the "correct" way depends on what you are doing with those errors. Are you logging them, reporting them to the user, propagating them to the caller? It just depends.
In my rough investigation, I think any errors can be handled by using if-then-else construct. Let's take a simple example as follows.
Division by zero can be handled with
int x=1;
int y=0;
if(y==0)
Console.WriteLine("undefined");
else
Console.WriteLine("x/y={0}",x/y);
to replace the try-catch equivalent
int x=1;
int y=0;
try
{
Console.WriteLine("x/y={0}",x/y);
}
catch
{
Console.WriteLine("undefined");
}
If try-catch can be replaced by if-then-else, which one is recommended?
You should never use exceptions for flow of control.
Exceptions should be "exceptional". If you know the rules for some data validation, you should use normal if/then/elses.
If you are doing some operation that can go wrong multiple ways (like connecting to a db) you should put that operation into a try-catch block and act accordingly.
Alas, the choice to treat something as "exceptional" goes into the designer's judgement.
EDIT: Also, do not underestimate the power of logging. Since I started using logging frameworks, my debugging time got cut by half.
Not all errors for the simple reason that there are some unexpected errors and this is where you want to use a try-catch statement. However, it isin't a good practice to use try-catch for things that you can prevent going wrong.
Additionnaly, I would only catch exceptions that I know how to handle or that can be handled, otherwise you will be blindly swallowing every exceptions and your application will be extremely hard to debug.
However, if you don't know how to handle an exception but you know that your application can recover from an error in that portion of code and want to avoid your application to crash because of an unhandled exception, it could by fine to use a try-catch block, but it would also be a good idea to log the exception details.
The try-catch block is the most efficient measure when it comes to Exception Handling. Here in this you are talking about a very simple and basic example, but there are lot many cases in the programming when there are multiple errors or exceptionn that could be found to a single expression. It is always prefer to go with (try-catch) block instead of checking for each condition.
Because you don't alawys simply want to communicate an error by simply spewing data to the console. That is usually the course of last resort.
typically, you want to develop a structured error handling system. One notable featured of a structured system like this is is the ability to communicate an error condition to the caller of a function or procedure. in this instance if the caller is aware that there may be esceptional circumstances and is prepared to deal with this error communication from the callee, it is done so.
howeer, exception have a special property , that they will continue to exist as long as they are uncaught, going further and further back up the chain of callers until the 'signal' , the error, they represent is handled.
many times, errors ( exceptions ) ARE caught and dealt with ( handled ) without sending anything to the console.
The up-chaining, propagating exception system provides a baked-in-the-compiler , syntactically clean way of providing structured error handling.
error codes or signals can also be used for this purpose, but are not quite as syntactically smooth, and leave a lot of traces in the coding, of there being a lot of error handling code. Exceptions try to hide error handling, except where it is absolutely necessary, by using the compiler and runtime to keep track of error code status automatially.
You can use both.
Without try catch it is hard to find what specific error your code throws.
try
{
int x=1;
int y=0;
if(y==0)
Console.WriteLine("undefined");
else
Console.WriteLine("x/y={0}",x/y);
}
catch
{
Console.WriteLine("undefined");
}
Best Regards
I wanted to add to this another important reason why in C# and many languages it's bad practice.
It's slow!
I had a situation where I was using try catch for flow control early on and it took about 15 ms to process the catch, where when I re-wrote it into a if-then statement it only took 1 ms when it hit the else (the catch). Some other languages are very efficient at try catch such as python and can use them in unique ways that C# should never do.
try catch is efficient in large or small codes because when you put your code that you think maybe error occurred in this section of code . and then you catch the exceptions of your code if it occurred in run time. and if you want run a line of code that is important for running like you want to call GC or handle your memory allocation and free it and etc, you can put these codes in finally section and its completely support all type of code .and its a good way for exception handling.
try{code that you think maybe error occurred }
catch {if error or exception occurred how handle it }
finally{all code that you want run when program has exception or has not }
The try catch in your case does not process the same logic as your if statement. You just implicitly assume it does. y == 0 is totally different from assuming that the only error which might occur is when y is 0.
So basically a programmer does not know for sure what might cause the branching code.
See also this article, which states, that using try-catch for flow control violates the 'principle of least astonishment': Why not use exceptions as regular flow of control?
The block TRY..CATCH does not replace IF..ELSE! They are two diffeent things.
The TRY..CATCH block catches errors, if ever there is one, whereas the IF..ELSE is a condition. If the 1st condition is false, it'll execute the ELSE part.
The best practice however would be to use the two;
try
{
if(y==0)
{
Console.WriteLine("undefined");
}
else
{
Console.WriteLine("x/y={0}",x/y);
}
}
catch (Exception ex)
{
Console.WriteLine("Error" + ex);
}
In this case here, if y was declared as Date for example, the condition would throw an error as (y==0) won't be evaluated. Thus sending you to the CATCH, which will throw you the conversion type error.
On the other hand, if y is declared as int (as in your example), there's not error evaluating (y==0) and hence, the IF..ELSE block will be executed.
Using Try/Catch block is the best way since through exception management we can LOG these errors into any file OR we can throw this exception to the parent function within the application. Also any new programmer also can understand the code more clearly since you have used try/catch blocks.
Thanks,
Skyrim.
I know you're not suppose to write code that caches all exception types like this.
try
{
//code that can throw an exception
}
catch
{
//what? I don't see no
}
Instead you're suppose to do something more like the code below allowing any other exception that you didn't expect to bubble up.
try
{
//code that can throw an exception
}
catch(TypeAException)
{
//TypeA specific code
}
catch(TypeBException)
{
//TypeB specific code
}
But is it ok to catch all exception types if you are wrapping them with another exception?
Consider this Save() method below I am writing as part of a Catalog class. Is there anything wrong with me catching all exception types and returning a single custom CatalogIOException with the original exception as the inner exception?
Basically I don't want any calling code to have to know anything about all the specific exceptions that could be thrown inside of the Save() method. They only need to know if they tried to save a read only catalog (CatalogReadOnlyException), the catalog could not be serialized (CatalogSerializationException), or if there was some problem writing to the file (CatalogIOException).
Is this a good or bad way to handle exceptions?
/// <summary>
/// Saves the catalog
/// </summary>
/// <exception cref="CatalogReadOnlyException"></exception>
/// <exception cref="CatalogIOException"></exception>
/// <exception cref="CatalogSerializingExeption"></exception>
public void Save()
{
if (!this.ReadOnly)
{
try
{
System.Xml.Serialization.XmlSerializer serializer = new XmlSerializer(typeof(Catalog));
this._catfileStream.SetLength(0); //clears the file stream
serializer.Serialize(this._catfileStream, this);
}
catch (InvalidOperationException exp)
{
throw new CatalogSerializationException("There was a problem serializing the catalog", exp);
}
catch (Exception exp)
{
throw new CatalogIOException("There was a problem accessing the catalog file", exp);
}
}
else
{
throw new CatalogReadOnlyException();
}
}
Update 1
Thanks for all the responses so far. It sounds like the consensus is I shouldn't be doing this, and I should only be catching exceptions if I actually have something to do with them. In the case of this Save() method there really isn't any exception that may be thrown that I want to handle in the Save() method itself. Mostly I just want to notify the user why they were not able to save.
I think my real problem is I'm using exceptions as a way to notify the user of problems, and I'm letting this inform how I am creating and handling exceptions a little too much. So instead should it sounds like it would be better to not catch any exceptions and let the UI layer figure out how to notify the user, and or crash. Is this correct? Consider the Save Menu event handler below.
private void saveCatalogToolStripMenuItem_Click(object sender, EventArgs e)
{
//Check if the catalog is read only
if (this.Catalog.ReadOnly)
{
MessageBox.Show("The currently opened catalog is readonly and can not be saved");
return;
}
//attempts to save
try
{
//Save method doesn't catch anything it can't deal with directly
this.Catalog.Save();
}
catch (System.IO.FileNotFoundException)
{
MessageBox.Show("The catalog file could not be found");
}
catch (InvalidOperationException exp)
{
MessageBox.Show("There was a problem serializing the catalog for saving: " + exp.Message);
}
catch (System.IO.IOException exp)
{
MessageBox.Show("There was a problem accessing the catalog file: " + exp.Message);
}
catch (Exception exp)
{
MessageBox.Show("There was a problem saving the catalog:" + exp.Message);
}
}
Update 2
One more thing. Would the answer change at all if the Save() method was part of a public API vs internal code? For example if it was part of a public API then I'd have to figure out and document all the possible exceptions that Save() may throw. This would be a lot easier if knew that Save() could only possibly throw one of my three custom exceptions.
Also if Save() was part of a public API wouldn't security also be a concern? Maybe I would want to let the consumer of the API know that the save wasn't successful, but I don't want expose anything about how Save() works by letting them get at the exceptions that may have been generated.
Doing a generic catch-all and rethrowing as a new type of exception does not really solve your problem and does not give you anything.
What you really need to do is to catch the exceptions that you can handle and then handle them (at the appropriate level - this is where rethrowing may be useful). All other exceptions either need to be logged so you can debug why they happened, or shouldn't be happening in the first place (for example - make sure you validate user input, etc.). If you catch all exceptions, you'll never really know why you're getting the exceptions you're getting and, thus, cannot fix them.
Updated Response
In response to the update of your question (particularly in how you want to handle the save case), my question to you would be - why are you using exceptions as a means of determine the path your program takes? For example, let's take the "FileNotFoundException." Obviously that can happen at times. But, instead of letting a problem happen and notifying the user about it, before saving (or doing whatever) with the file, why not check first that the file can be found. You still get the same effect, but you aren't using exceptions to control program flow.
I hope this all makes sense. Let me know if you have any additional questions.
When you re-throw with the original exception as inner exception, you lose the original stack trace, which is valuable debugging information.
I will sometimes do what you are suggesting, but I always log the original exception first to preserve the stack trace.
I don't see a problem with what you are doing. The reason for wrapping exceptions in a custom exception types is to create an abstraction between layers of code -- to translate lower-level errors into a higher-level context. Doing this relieves the calling code from having to know too much the implementation details of what Save does.
Your update #1 is an example of the calling code having to know way too much about the implementation details of Save(). In response to your second update, I agree 100%
PS
I'm not saying to do this in every scenario where you encounter exceptions. Only when the benefit outweighs the cost (usually at module boundaries).
Example scenarios for when this is especially useful: you are wrapping a 3rd party library, you don't yet know all the underlying exceptions that might be thrown, you don't have the source code or any documentation, and so on.
Also, he is wrapping the underlying exception and no information is lost. The exception can still be logged appropriately (though you'll need to recursion your way through the InnerExceptions).
I favor wrapping exceptions, from the standpoint that a custom exception hierarchy can divide exceptions into much more useful classifications than the default hierarchy. Suppose one tries to open a document and gets an ArgumentException or an InvalidOperationException. Does the type of the exception really contain any useful information whatsoever? Suppose, however, one instead got a CodecNotFoundException, a PrerenderFingFailureException, or a FontLoadFailureException. One can imagine the system catching some of those exceptions and attempting to do something about it (e.g. allow the user to search for a CODEC, retry rendering with lower-resolution settings, or allow substitution of fonts after warning the user). Much more useful than the default exceptions, many of which say nothing about what's really wrong or what can be done about it.
From a hierarchical standpoint, what's really needed is a means of distinguishing exceptions which indicate that the method throwing the exception was unable to perform its task, but the system state is similar to what it was before the method was started, and those which indicate that the system state is corrupt in a fashion beyond that implied by the method's failure. The normal exception hierarchy is completely useless for that; if one wraps exceptions one may be able to improve the situation slightly (though not as well as if the hierarchy were better designed to start with). An exception which forces a transaction to be unwound is not nearly as bad as one which occurs while committing or unwinding a transaction. In the former case, the state of the system is known; in the latter case, it isn't.
While one should probably avoid catching certain really bad exceptions (StackOverflowException, OutOfMemoryException, ThreadAbortException) I'm not sure it really matters. If the system is going to crash and burn, it's going to do so whether one catches the exception or not. In vb.net, it may be worthwhile to "Catch Ex As Exception When IsNotHorribleException(Ex)" but C# has no such construct, nor even a way to exclude certain exceptions from being caught.
Parting note: in some cases, one operation may generate multiple exceptions that are worthy of logging. Only by wrapping exceptions in a custom exception which holds a list of other exceptions can that really be accomplished.
I don't think its a good idea.
You should only add you own type of exception, if you have anything to add.
And furthermore, you should only catch exceptions that you expect, and that you are able to handle - all other exceptions should be allowed to bubble up.
As a developer I must say, I get angry if you try to "hide" exceptions from me, by swallowing or wrapping them.
For some more info on why catch(exception) is bad check out this article: http://blogs.msdn.com/clrteam/archive/2009/02/19/why-catch-exception-empty-catch-is-bad.aspx
Essentially catching 'Exception' is like saying 'if anything goes wrong I dont care carry on' and catching 'Exception' and wrapping it is like saying 'if anything goes wrong treat them as if they all went wrong for the exact same reason'.
This cannot be correct either you handle it because you semi-expected it or you totally don't think it should ever happen EVER (or didn't know it would). In this case you'd want some kind of app level logging to point you to an issue that you had never expected - not just a one size fits all solution.
My own rule of thumb is to catch and wrap Exception only if I have some useful context I can add, like the file name I was trying to access, or the connection string, etc. If an InvalidOperationException pops up in your UI with no other information attached, you're going to have a hell of a time tracking down the bug.
I catch specific exception types only if the context or message I want to add can be made more useful for that exception compared to what I would say for Exception generally.
Otherwise, I let the exception bubble up to another method that might have something useful to add. What I don't want to do is tie myself in knots trying to catch and declare and handle every possible exception type, especially since you never know when the runtime might throw a sneaky ThreadAbortException or OutOfMemoryException.
So, in your example, I would do something like this:
try
{
System.Xml.Serialization.XmlSerializer serializer =
new XmlSerializer(typeof(Catalog));
this._catfileStream.SetLength(0); //clears the file stream
serializer.Serialize(this._catfileStream, this);
}
// catch (InvalidOperationException exp)
// Don't catch this because I have nothing specific to add that
// I wouldn't also say for all exceptions.
catch (Exception exp)
{
throw new CatalogIOException(
string.Format("There was a problem accessing catalog file '{0}'. ({1})",
_catfileStream.Name, exp.Message), exp);
}
Consider adding the inner exception's message to your wrapper exception so that if a user just sends you a screenshot of the error dialog, you at least have all the messages, not just the top one; and if you can, write the whole ex.ToString() to a log file somewhere.
In this particular case exceptions should be rare enough that wrapping it shouldn't be a useful thing and will likely just get in the way of error handling down the line. There are plenty of examples within the .Net framework where a specific exception that I can handle is wrapped in a more general one and it makes it much more difficult (though not impossible) for me to handle the specific case.
I have written an article on this very topic before. In it I reiterate the importance of capturing as much data about the exception as is possible. Here's the URL to the article:
http://it.toolbox.com/blogs/paytonbyrd/improve-exception-handling-with-reflection-and-generics-8718
What benefit does the user get from being told "There was a problem serializing the catalog"? I suppose your problem domain might be an extraordinary case, but every group of users I've ever programmed for would respond the same way when reading that message: "The program blew up. Something about the catalog."
I don't mean to be condescending towards my users; I'm not. It's just that generally speaking my users have better things to do with their attention than squander it constructing a fine-grained mental model of what's going on inside my software. There have been times when my users have had to build that kind of an understanding in order to use a program I've written, and I can tell you that the experience was not salutary for them or for me.
I think your time would be much better spent on figuring out how to reliably log exceptions and relevant application state in a form that you can access when your users tell you that something broke than in coming up with an elaborate structure for producing error messages that people are unlikely to understand.
To answer this question, you need to understand why catching System.Exception is a bad idea, and understand your own motivations for doing what your propose.
It's a bad idea because it makes the statement that anything that could have gone wrong is okay, and that the application is in a good state to keep running afterwards. That's a very bold statement to make.
So the question is: Is what you are proposing equivalent to catching System.Exception? Does it give the consumer of your API any more knowledge to make a better judgement? Does it simply encourage them to catch YourWrappedException, which is then the moral equivalent of catching System.Exception, except for not triggering FXCop warnings?
In most cases, if you know there's a rule against doing something, and want to know if something similar is "okay", you should start with understanding the rationale for the original rule.
This is a standard practice in .NET and how exceptions should be handled, especially for exceptions that are recoverable from.
Edit: I really have no idea why I'm being downvoted perhaps I read more into the authors intent than everyone else. But the way I read the code the fact he is wrapping those exceptions into his custom exception implies that the consumer of this method is equiped to handle those exceptions and that it is a responsibility of the consumer to deal with the error processing.
Not a single person that DV'd actually left any form of actual dispute. I stand by my answer that this is perfectly acceptable because the consumer should be aware of the potential exceptions this could throw and be equipped to handle them which is shown by the explicit wrapping of the exception. This also preserves the original exception so the stack trace is available and underlying exception accessible.
I know it sounds weird but I am required to put a wrapping try catch block to every method to catch all exceptions. We have thousands of methods and I need to do it in an automated way. What do you suggest?
I am planning to parse all cs files and detect methods and insert a try catch block with an application. Can you suggest me any parser that I can easily use? or anything that will help me...
every method has its unique number like 5006
public static LogEntry Authenticate(....)
{
LogEntry logEntry = null;
try
{
....
return logEntry;
}
catch (CompanyException)
{
throw;
}
catch (Exception ex)
{
logEntry = new LogEntry(
"5006",
RC.GetString("5006"), EventLogEntryType.Error,
LogEntryCategory.Foo);
throw new CompanyException(logEntry, ex);
}
}
I created this for this;
http://thinkoutofthenet.com/index.php/2009/01/12/batch-code-method-manipulation/
DONT DO IT. There is no good reason for pokemon ("gotta catch em all")error handling.
EDIT: After a few years, a slight revision is in order. I would say instead "at least dont do this manually". Use an AOP tool or weaver like PostSharp or Fody to apply this to the end result code, but make sure to consider other useful tracing or diagnostic data points like capturing time of execution, input parameters, output parameters, etc.
Well if you have to do it, then you must. However, you might try to talk whoever is forcing you to do it into letting you use the UnhandledException event of the AppDomain class. It will give you a notification about every uncaught exception in any method before it is reported to the user. Since you can also get a stack trace from the exception object, you'll be able to tell exactly where every exception occurs. It is a much better solution than rigging your code with exception handlers everywhere.
With that said, if I had to do it, I'd use some regular expressions to identify the begin and end of each method and use that to insert some exception handler everywhere. The trick to writing a regular expression for this case will be Balancing Group Definition explained more in the MSDN documentation here. There is also a relevant example of using balancing groups here.
Maybe whoever came up with the requirement doesn't understand that you can still catch all exceptions (at the top) without putting a try-catch in every single function. You can see an example of how to catch all unhandled exceptions here. I think this is a much better solution as you can actually do something with the exception, and report it, rather than blindly burying all exceptions, resulting in extremely hard to track down bugs.
This is similar to Scott's solution, but also adds an event handler to the Application.ThreadException exception which can happen if you are using threads. Probably best to use both in order to catch all exceptions.
See my answer here which describes some of the performance trade offs you will be forced to live with if you use "gotta catch em all" exception handling.
As scott said the best way to do pretty much the same thing is the UnhandledException event. I think jeff actually discussed this very problem in an early SO podcast.
I'm with StingyJack, don't do it!
However if the Gods on high decree that must be done, then see my answer to this question Get a method’s contents from a cs file
First of all, I'm with StingyJack and Binary Worrier. There's a good reason exceptions aren't caught by default. If you really want to catch exceptions and die slightly nicer, you can put a try-catch block around the Application.Run() call and work from there.
When dealing with outside sources, (files, the Internet, etc), one should (usually) catch certain exceptions (bad connection, missing file, blah blah). In my book, however, an exception anywhere else means either 1) a bug, 2) flawed logic, or 3) poor data validation...
In summary, and to completely not answer your question, are you sure you want to do this?
I had to do something kinda sorta similar (add something to a lot of lines of code); I used regex.
I would create a regex script that found the beginning of each function and insert the try catch block right after the beginning. I would then create another regex script to find the end of the function (by finding the beginning of the function right after it) and insert the try catch block at the end. This won't get you 100% of the way there, but it will hit maybe 80% which would hopefully be close enough that you could do the edge cases without too much more work.
I wanted to write this as an answer to all answers then you can be aware via question RSS;
requirement comes from our technical leader:
here is his reason:
we need no find out which func has a problem in production code, any problem has been reported as an alert, we put a unique code to ecery catch block and we see where the problem is. He knows there is a global error handling but it does not help in this scenario, and stacktrace is not accure in release mode, so he requires a try catch block like this:
everyMethod(...){
try
{
..
catch(Exception e)
{
RaiseAlert(e.Message.. blabla)
}
}
If you put a RaiseAlert call in every method, the error stacks you receive will be very confusing, if not inaccurate, assuming that you reuse methods. The logging method should really only need to be called in events or the top-most method(s). If someone is pushing the issue that exception handling needs to be in every method, they don't understand exception handling.
A couple years back we implemented a practice that exception handling had to be done in every event and one developer read it as "every method." When they were finished, we had weeks worth undoing to do because no exception reported was ever reproducible. I'm assuming they knew better, like you do, but never questioned the validity of their interpretation.
Implementing AppDomain.UnhandledException is a good backup but your only recourse in that method is to kill the application once you log the exception. You'd have to write a global exception handler to prevent this.
so here is an example for those wondering;
5006 is unique to this method;
public static LogEntry Authenticate(....)
{
LogEntry logEntry = null;
try
{
....
return logEntry;
}
catch (CompanyException)
{
throw;
}
catch (Exception ex)
{
logEntry = new LogEntry(
"5006",
RC.GetString("5006"), EventLogEntryType.Error,
LogEntryCategory.Foo);
throw new CompanyException(logEntry, ex);
}
}
I guess you could use Aspect Oriented programming, something I would like to my hands dirty with. For example http://www.postsharp.org/aopnet/overview
Although this sort of requirements are indeed evil.
If you really have to do it, why go to the trouble of modifying the source code, when you can modify the compiled executable/library directly
Have a look at Cecil (see website), It's a library that allows you to modify the bytecode directly, using this approach, your entire problem could be solved in a couple of hundred lines of C# code.
Since you are posting a question here, I am sure this is one of those things you just have to do. So instead of banging your head against an unyielding wall, why not do what Scott suggested and use the AppDomain event handler. You'll meet the requirements without spending hours of quality billable hours doing grunt work. I am sure once you tell your boss how much testing updating each and every file would entail, using the event handler will be a no-brainer!
So you are not really looking to put the same exact try-catch block in each function, right? You are going to have to tailor each try-catch to each function. Wow! Seems like a long way to "simplify" debugging.
If a user reports an error in production, why can't you just fire up Visual Studio and reproduce the steps and debug?
If you absolutely have to add the try/catch block to every method and scott's answer (AppDomain.UnhandledException) is not sufficient, you can also look into interceptors. I believe the Castle project has a fairly good implementation of method interceptors.
If you really have to do it, an alternative to wrapping the exception each time would be to use Exception.Data to capture the additional information and then rethrow the original exception ...
catch (Exception ex)
{
logEntry = new LogEntry("5006",
RC.GetString("5006"), EventLogEntryType.Error,
LogEntryCategory.Foo);
ex.Data.Add("5006",logEntry);
throw;
}
Now at the top level you can just dump the contents of ex.Data to get all the additional information you might want. This allows you to put file names, useragents, ... and all manner of other useful information in the .Data collection to help understand why an exception occurred.
I did some research work that require parsing of C# code about 2 years ago and discover that the SharpDevelop project has source code that does this really well. If you extracted the SharpDevParser project (this was two years ago, not sure if the project name stays the same) from the source code base, you can then use the parser object like this:
CSharpBinding.Parser.TParser = new CSharpBinding.Parser.TParser();
SIP.ICompilationUnitBase unitBase = sharpParser.Parse(fileName);
this gives you the compUnit.Classes which you can iterate through each class and find method within it.
I was helping a friend find a memory leak in a C# XNA Game he was writing.
I suggested we try and examine how many times each method was getting invoked.
In order to keep count, I wrote a python script that added 2 lines to update a Dictionary with the details.
Basically I wrote a python script to modify some 400~ methods with 2 required lines.
This code may help someone do more things, like the odd thing the OP wanted.
The code uses the path configured on the 3rd line, and iterates recursively while processing .cs files. It does sub-directories as well.
When it find a cs file, it looks for method declarations, it tries to be as careful as possible. MAKE A BACKUP - I AM NOT RESPONSIBLE IF MY SCRIPT VIOLATES YOUR CODE!!!
import os, re
path="D:/Downloads/Dropbox/My Dropbox/EitamTool/NetworkSharedObjectModel"
files = []
def processDir(path, files):
dirList=os.listdir(path)
for fname in dirList:
newPath = os.path.normpath(path + os.sep + fname)
if os.path.isdir(newPath):
processDir(newPath, files)
else:
if not newPath in files:
files.append(newPath)
newFile = handleFile(newPath)
if newPath.endswith(".cs"):
writeFile(newPath, newFile)
def writeFile(path, newFile):
f = open(path, 'w')
f.writelines(newFile)
f.close()
def handleFile(path):
out = []
if path.endswith(".cs"):
f = open(path, 'r')
data = f.readlines()
f.close()
inMethod = False
methodName = ""
namespace = "NotFound"
lookingForMethodDeclerationEnd = False
for line in data:
out.append(line)
if lookingForMethodDeclerationEnd:
strippedLine = line.strip()
if strippedLine.find(")"):
lookingForMethodDeclerationEnd = False
if line.find("namespace") > -1:
namespace = line.split(" ")[1][0:-2]
if not inMethod:
strippedLine = line.strip()
if isMethod(strippedLine):
inMethod = True
if strippedLine.find(")") == -1:
lookingForMethodDeclerationEnd = True
previousLine = line
else:
strippedLine = line.strip()
if strippedLine == "{":
methodName = getMethodName(previousLine)
out.append(' if (!MethodAccess.MethodAccess.Counter.ContainsKey("' + namespace + '.' + methodName + '")) {MethodAccess.MethodAccess.Counter.Add("' + namespace + '.' + methodName + '", 0);}')
out.append("\n" + getCodeToInsert(namespace + "." + methodName))
inMethod = False
return out
def getMethodName(line):
line = line.strip()
lines = line.split(" ")
for littleLine in lines:
index = littleLine.find("(")
if index > -1:
return littleLine[0:index]
def getCodeToInsert(methodName):
retVal = " MethodAccess.MethodAccess.Counter[\"" + methodName + "\"]++;\n"
return retVal
def isMethod(line):
if line.find("=") > -1 or line.find(";") > -1 or line.find(" class ") > -1:
return False
if not (line.find("(") > -1):
return False
if line.find("{ }") > -1:
return False
goOn = False
if line.startswith("private "):
line = line[8:]
goOn = True
if line.startswith("public "):
line = line[7:]
goOn = True
if goOn:
return True
return False
processDir(path, files)
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I'm stuck deciding how to handle exceptions in my application.
Much if my issues with exceptions comes from 1) accessing data via a remote service or 2) deserializing a JSON object. Unfortunately I can't guarantee success for either of these tasks (cut network connection, malformed JSON object that is out of my control).
As a result, if I do encounter an exception I simply catch it within the function and return FALSE to the caller. My logic is that all the caller really cares about is if the task was successful, not why it is wasn't successful.
Here's some sample code (in JAVA) of a typical method)
public boolean doSomething(Object p_somthingToDoOn)
{
boolean result = false;
try{
// if dirty object then clean
doactualStuffOnObject(p_jsonObject);
//assume success (no exception thrown)
result = true;
}
catch(Exception Ex)
{
//don't care about exceptions
Ex.printStackTrace();
}
return result;
}
I think this approach is fine, but I'm really curious to know what the best practices are for managing exceptions (should I really bubble an exception all the way up a call stack?).
In summary of key questions:
Is it okay to just catch exceptions but not bubble them up or formally notifying the system (either via a log or a notification to the user)?
What best practices are there for exceptions that don't result in everything requiring a try/catch block?
Follow Up/Edit
Thanks for all the feedback, found some excellent sources on exception management online:
Best Practices for Exception Handling | O'Reilly Media
Exception Handling Best Practices in .NET
Best Practices: Exception Management (Article now points to archive.org copy)
Exception-Handling Antipatterns
It seems that exception management is one of those things that vary based on context. But most importantly, one should be consistent in how they manage exceptions within a system.
Additionally watch out for code-rot via excessive try/catches or not giving a exception its respect (an exception is warning the system, what else needs to be warned?).
Also, this is a pretty choice comment from m3rLinEz.
I tend to agree with Anders Hejlsberg and you that the most callers only
care if operation is successful or not.
From this comment it brings up some questions to think about when dealing with exceptions:
What is the point this exception being thrown?
How does it make sense to handle it?
Does the caller really care about the exception or do they just care if the call was successful?
Is forcing a caller to manage a potential exception graceful?
Are you being respectful to the idoms of the language?
Do you really need to return a success flag like boolean? Returning boolean (or an int) is more of a C mindset than a Java (in Java you would just handle the exception) one.
Follow the error management constructs associated with the language :) !
It seems odd to me that you want to catch exceptions and turn them into error codes. Why do you think the caller would prefer error codes over exceptions when the latter is the default in both Java and C#?
As for your questions:
You should only catch exceptions that you can actually handle. Just
catching exceptions is not the right thing to do in most cases.
There are a few exceptions (e.g. logging and marshalling exceptions
between threads) but even for those cases you should generally
rethrow the exceptions.
You should definitely not have a lot of try/catch statements in your
code. Again, the idea is to only catch exceptions you can handle.
You may include a topmost exception handler to turn any unhandled
exceptions into something somewhat useful for the end user but
otherwise you should not try to catch each and every exception in
every possible place.
This depends on the application and the situation. If your building a library component, you should bubble up exceptions, although they should be wrapped to be contextual with your component. For example if your building an Xml Database and let's say you are using the file system to store your data, and you are using file system permissions to secure the data. You wouldn't want to bubble up a FileIOAccessDenied exception as that leaks your implementation. Instead you would wrap the exception and throw an AccessDenied error. This is especially true if you distribute the component to third parties.
As for if it's okay to swallow exceptions. That depends on your system. If your application can handle the failure cases and there is no benefit from notifying the user why it failed then go ahead, although I highly recommend that your log the failure. I've always found it frustating being called to help troubleshoot an issue and find they were swallowing the exception (or replacing it and throwing a new one instead without setting the inner exception).
In general I use the following rules:
In my components & libraries I only catch an exception if I intend to handle it or do something based on it. Or if I want to provide additional contextual information in an exception.
I use a general try catch at the application entry point, or the highest level possible. If an exception gets here I just log it and let it fail. Ideally exceptions should never get here.
I find the following code to be a smell:
try
{
//do something
}
catch(Exception)
{
throw;
}
Code like this serves no point and should not be included.
I would like to recommend another good source on the topic. It's an interview with inventors of C# and Java, Anders Hejlsberg and James Gosling respectively, on the topic of Java's Checked Exception.
Failure and Exceptions
There are also great resources at the bottom of the page.
I tend to agree with Anders Hejlsberg and you that the most callers only care if operation is successful or not.
Bill Venners: You mentioned
scalability and versioning concerns
with respect to checked exceptions.
Could you clarify what you mean by
those two issues?
Anders Hejlsberg: Let's start with
versioning, because the issues are
pretty easy to see there. Let's say I
create a method foo that declares it
throws exceptions A, B, and C. In
version two of foo, I want to add a
bunch of features, and now foo might
throw exception D. It is a breaking
change for me to add D to the throws
clause of that method, because
existing caller of that method will
almost certainly not handle that
exception.
Adding a new exception to a throws
clause in a new version breaks client
code. It's like adding a method to an
interface. After you publish an
interface, it is for all practical
purposes immutable, because any
implementation of it might have the
methods that you want to add in the
next version. So you've got to create
a new interface instead. Similarly
with exceptions, you would either have
to create a whole new method called
foo2 that throws more exceptions, or
you would have to catch exception D in
the new foo, and transform the D into
an A, B, or C.
Bill Venners: But aren't you breaking
their code in that case anyway, even
in a language without checked
exceptions? If the new version of foo
is going to throw a new exception that
clients should think about handling,
isn't their code broken just by the
fact that they didn't expect that
exception when they wrote the code?
Anders Hejlsberg: No, because in a lot
of cases, people don't care. They're
not going to handle any of these
exceptions. There's a bottom level
exception handler around their message
loop. That handler is just going to
bring up a dialog that says what went
wrong and continue. The programmers
protect their code by writing try
finally's everywhere, so they'll back
out correctly if an exception occurs,
but they're not actually interested in
handling the exceptions.
The throws clause, at least the way
it's implemented in Java, doesn't
necessarily force you to handle the
exceptions, but if you don't handle
them, it forces you to acknowledge
precisely which exceptions might pass
through. It requires you to either
catch declared exceptions or put them
in your own throws clause. To work
around this requirement, people do
ridiculous things. For example, they
decorate every method with, "throws
Exception." That just completely
defeats the feature, and you just made
the programmer write more gobbledy
gunk. That doesn't help anybody.
EDIT: Added more details on the converstaion
Checked exceptions are a controversial issue in general, and in Java in particular (later on I'll try to find some examples for those in favor and opposed to them).
As rules of thumb, exception handling should be something around these guidelines, in no particular order:
For the sake of maintainability, always log exceptions so that when you start seeing bugs, the log will assist in pointing you to the place your bug has likely started. Never leave printStackTrace() or the likes of it, chances are one of your users will get one of those stack traces eventually, and have exactly zero knowledge as to what to do with it.
Catch exceptions you can handle, and only those, and handle them, don't just throw them up the stack.
Always catch a specific exception class, and generally you should never catch type Exception, you are very likely to swallow otherwise important exceptions.
Never (ever) catch Errors!!, meaning: Never catch Throwables as Errors are subclasses of the latter. Errors are problems you will most likely never be able to handle (e.g. OutOfMemory, or other JVM issues)
Regarding your specific case, make sure that any client calling your method will receive the proper return value. If something fails, a boolean-returning method might return false, but make sure the places you call that method are able to handle that.
You should only catch the exceptions you can deal with. For example, if you're dealing with reading over a network and the connection times out and you get an exception you can try again. However if you're reading over a network and get a IndexOutOfBounds exception, you really can't handle that because you don't (well, in this case you wont) know what caused it. If you're going to return false or -1 or null, make sure it's for specific exceptions. I don't want a library I'm using returning a false on a network read when the exception thrown is the heap is out of memory.
Exceptions are errors that are not part of normal program execution. Depending on what your program does and its uses (i.e. a word processor vs. a heart monitor) you will want to do different things when you encounter an exception. I have worked with code that uses exceptions as part of normal execution and it is definitely a code smell.
Ex.
try
{
sendMessage();
if(message == success)
{
doStuff();
}
else if(message == failed)
{
throw;
}
}
catch(Exception)
{
logAndRecover();
}
This code makes me barf. IMO you should not recover from exceptions unless its a critical program. If your throwing exceptions then bad things are happening.
All of the above seems reasonable, and often your workplace may have a policy. At our place we have defined to types of Exception: SystemException (unchecked) and ApplicationException (checked).
We have agreed that SystemExceptions are unlikely to be recoverable and will bve handled once at the top. To provide further context, our SystemExceptions are exteneded to indicate where they occurred, e.g. RepositoryException, ServiceEception, etc.
ApplicationExceptions could have business meaning like InsufficientFundsException and should be handled by client code.
Witohut a concrete example, it's difficult to comment on your implementation, but I would never use return codes, they're a maintenance issue. You might swallow an Exception, but you need to decide why, and always log the event and stacktrace. Lastly, as your method has no other processing it's fairly redundant (except for encapsulation?), so doactualStuffOnObject(p_jsonObject); could return a boolean!
After some thought and looking at your code it seems to me that you are simply rethrowing the exception as a boolean. You could just let the method pass this exception through (you don't even have to catch it) and deal with it in the caller, since that's the place where it matters. If the exception will cause the caller to retry this function, the caller should be the one catching the exception.
It can at times happen that the exception you are encountering will not make sense to the caller (i.e. it's a network exception), in which case you should wrap it in a domain specific exception.
If on the other hand, the exception signals an unrecoverable error in your program (i.e. the eventual result of this exception will be program termination) I personally like to make that explicit by catching it and throwing a runtime exception.
If you are going to use the code pattern in your example, call it TryDoSomething, and catch only specific exceptions.
Also consider using an Exception Filter when logging exceptions for diagnostic purposes. VB has language support for Exception filters. The link to Greggm's blog has an implementation that can be used from C#. Exception filters have better properties for debuggability over catch and rethrow. Specifically you can log the problem in the filter and let the exception continue to propagate. That method allows an attaching a JIT (Just in Time) debugger to have the full original stack. A rethrow cuts the stack off at the point it was rethrown.
The cases where TryXXXX makes sense are when you are wrapping a third party function that throws in cases that are not truly exceptional, or are simple difficult to test without calling the function. An example would be something like:
// throws NumberNotHexidecimalException
int ParseHexidecimal(string numberToParse);
bool TryParseHexidecimal(string numberToParse, out int parsedInt)
{
try
{
parsedInt = ParseHexidecimal(numberToParse);
return true;
}
catch(NumberNotHexidecimalException ex)
{
parsedInt = 0;
return false;
}
catch(Exception ex)
{
// Implement the error policy for unexpected exceptions:
// log a callstack, assert if a debugger is attached etc.
LogRetailAssert(ex);
// rethrow the exception
// The downside is that a JIT debugger will have the next
// line as the place that threw the exception, rather than
// the original location further down the stack.
throw;
// A better practice is to use an exception filter here.
// see the link to Exception Filter Inject above
// http://code.msdn.microsoft.com/ExceptionFilterInjct
}
}
Whether you use a pattern like TryXXX or not is more of a style question. The question of catching all exceptions and swallowing them is not a style issue. Make sure unexpected exceptions are allowed to propagate!
I suggest taking your cues from the standard library for the language you're using. I can't speak for C#, but let's look at Java.
For example java.lang.reflect.Array has a static set method:
static void set(Object array, int index, Object value);
The C way would be
static int set(Object array, int index, Object value);
... with the return value being a success indicator. But you're not in C world any more.
Once you embrace exceptions, you should find that it makes your code simpler and clearer, by moving your error handling code away from your core logic. Aim to have lots of statements in a single try block.
As others have noted - you should be as specific as possible in the kind of exception you catch.
If you're going to catch an Exception and return false, it should be a very specific exception. You're not doing that, you're catching all of them and returning false. If I get a MyCarIsOnFireException I want to know about it right away! The rest of the Exceptions I might not care about. So you should have a stack of Exception handlers that say "whoa whoa something is wrong here" for some exceptions (rethrow, or catch and rethrow a new exception that explains better what happened) and just return false for others.
If this is a product that you'll be launching you should be logging those exceptions somewhere, it will help you tune things up in the future.
Edit: As to the question of wrapping everything in a try/catch, I think the answer is yes. Exceptions should be so rare in your code that the code in the catch block executes so rarely that it doesn't hit performance at all. An exception should be a state where your state machine broke and doesn't know what to do. At least rethrow an exception that explains what was happening at the time and has the caught exception inside of it. "Exception in method doSomeStuff()" isn't very helpful for anyone who has to figure out why it broke while you're on vacation (or at a new job).
My strategy:
If the original function returned void I change it to return bool. If exception/error occurred return false, if everything was fine return true.
If the function should return something then when exception/error occurred return null, otherwise the returnable item.
Instead of bool a string could be returned containing the description of the error.
In every case before returning anything log the error.
Some excellent answers here. I would like to add, that if you do end up with something like you posted, at least print more than the stack trace. Say what you were doing at the time, and Ex.getMessage(), to give the developer a fighting chance.
try/catch blocks form a second set of logic embedded over the first (main) set, as such they are a great way to pound out unreadable, hard to debug spaghetti code.
Still, used reasonably they work wonders in readability, but you should just follow two simple rules:
use them (sparingly) at the low-level to catch library handling issues, and stream them back into the main logical flow. Most of the error handling we want, should be coming from the code itself, as part of the data itself. Why make special conditions, if the returning data isn't special?
use one big handler at the higher-level to manage any or all of the weird conditions arising in the code that aren't caught at a low-level. Do something useful with the errors (logs, restarts, recoveries, etc).
Other than these two types of error handling, all of the rest of the code in the middle should be free and clear of try/catch code and error objects. That way, it works simply and as expected no matter where you use it, or what you do with it.
Paul.
I may be a little late with the answer but error handling is something that we can always change and evolve along time. If you want to read something more about this subject I wrote a post in my new blog about it. http://taoofdevelopment.wordpress.com
Happy coding.