How can I get exception code in C#? - c#

Is there anything like exception code? that i can know that on different languages operation system i can recognize the same exception?
I need to recognize 'Acces to the COMn Port is denied' and then do some action, is that possible? has this exception any specified type?

From the sounds of it you will be getting a System.UnauthorizedAccessException (this assumption has been made from Googling the error message and finding this forum). To handle this, you would need to use catch clauses in a try-catch statement that are specific to this exception type. So, in C# you would do something like:
try
{
// ... Run some code that might cause the error in question ...
}
catch (System.UnauthorizedAccessException ex)
{
// ... Run some code that handles the error in question ...
}

There is no concept of a global exception code in .NET -- and there really could never be, since it implies that every author of every exception class on the planet would have to collaborate in order to choose codes.
You also cannot assume that a particular message signals an exception of a particular type, since the message can (in the general case) be freely chosen at the throw site.
You could do a type switch on exception.GetType() to find what the runtime type of an exception is, but that is not guaranteed to be a solution (it depends on what was actually thrown, which could be a vanilla System.Exception for all we know).
What exactly are you trying to achieve?

Related

If try-catch can be replaced by if-then-else, which one is recommended?

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.

Throw a C# exception of the same type as that caught?

why (if at all) is this a bad idea ?
class Program
{
static void Main(string[] args)
{
try
{
throw new NotImplementedException("Oh dear");
}
catch (Exception ex)
{
throw NewException("Whoops", ex);
}
}
// This function is the salient bit here
public static Exception NewException(String message, Exception innerException)
{
return Activator.CreateInstance(innerException.GetType(), message, innerException) as Exception;
}
}
The important bit here is that the function creates an exception of the same type as the "innerException".
I'm thinking... "Oh... an exception has occurred. I can't actually handle it here, but I can add some additional information, and re-throw. Maybe another handler, higher up the call chain can handle it."
A case in point might be some sort of SQL error. I might not be able to handle the exception at the point of calling, but might wish to add some additional "context" information like "I was calling this, and passing that".
It seems like it might be useful to pass back up the call chain an exception of the type that was originally raised, as opposed to "Exception" or "ApplicationException". I know I could create my own custom exception classes, but it seems that it adds nothing much when you already have a nice specific exception.
Of course, I might be wrong. It might be a very useful thing to do... but a little voice is suggesting not.
----- edit -----
For the sake of debate, consider the effects of the following two functions (using the code above):
This... seen all too often:
static int SalesTotal(int customerNumber)
{
try
{
throw new DivideByZeroException(); // something you didn't expect
}
catch (Exception ex)
{
throw new ApplicationException("Unable to calculate sales for customer " + customerNumber, ex);
}
}
versus this...
static int SalesTotal(int customerNumber)
{
try
{
throw new DivideByZeroException(); // something you didn't expect
}
catch (Exception ex)
{
throw NewException("Unable to calculate sales for customer " + customerNumber, ex);
}
}
all exceptions have a Data property that you can add additional data to. There is no need to create a new exception. Just catch the existing exception and add your information and then just rethrow the exception.
This way you get your cake and eat it too. :)
http://msdn.microsoft.com/en-us/library/system.exception_members(v=VS.90).aspx
Creating a new exception type isn't a good option for a general method like this, since existing code will be unable to react to a specific error. (Translation exceptions at API boundaries cane be useful, though).
Creating a new exception of the same type seems perilous. Does the CreateInstance overload you're using copy all fields from the innerException to your new outer exception? What if an exception handler higher up the stack depends on parsing the Message property? What if the exception constructor has side effects?
IMHO, what you're really doing is logging, and you'd probably be better off actually doing logging and a re-throw.
I think you should create your own custom exception type. What kind of information are you going to add? How is the catcher of the exception going to know it has extra information? If you use a custom type, they will have extra properties/methods to view or call.
Don't catch it at all and just let it bubble up - there's no point reinventing the wheel.
Not only is your method not intuitive for somebody else coming in, but you're also going to lose the original stack trace from the first exception.
It can make sense in some cases. If you consider MyClass.MyFunction the public "outside" of the assembly, then what happens inside it is a black box to calling code. It can therefore be more reasonable to have that as the point that the exception happened as far as the calling code goes, and the most reasonable type of exception could happen to be the same type as that caught.
I would be cautious though. In most cases of this happening, either you should have been able to catch that the exception was going to happen, and thrown pre-emptively (if you are going to throw, the sooner the better) or else the exception you are throwing isn't really the right type (if your code doesn't find a file it needs that's a FileNotFoundException to you, but if the files are an implementation detail, then it's not a FileNotFoundException to the calling code), or else the original exception will make perfect sense and it should just be allowed to call through or rethrown with throw;.
So, not always a bad idea, but bad often enough that it's always a suspicious thing to see.
IMHO, it would probably be good to have a few custom exception types, with one hierarchy for exceptions which say "This operation failed, but the system state is as though it had never been attempted", another for exceptions that say "The operation failed, and the system state has been disturbed, but it can probably be unwound", and another for "The operation failed, and unwinding failed; the system state cannot be trusted." In some contexts, one class of exception may be caught and rethrown as another (e.g. if an operation which was supposed to finish restoring system state fails, even if from the point of view of that operation nothing was disturbed, the failure to restore the state may leave it disturbed; conversely, if an operation left a system state disturbed but a catch handler restored the state, it could rethrow as an "operation failed but system state is undisturbed".
I dislike very much the idea of trying to create exception instances that blindly match thrown exception types, since the thrown exceptions may have fields which handlers will expect to be populated. I'm not sure why Microsoft made exceptions "almost" immutable. It would be much nicer if exceptions were required to be immutable and support cloning with whatever semantics conveyed immutability.
Only catch exceptions that you handle, for instance you do not want a SqlException to be thrown from your data layer to your business layer (catch it, try ot handle it and throw a DataLayerException or something like that instead).

Creating exception classes for lot different error codes

I am writing a custom .Net SDK for the mapping program MapInfo Pro, mapinfo only exposes two methods to use over COM void Do(string cmd) and string Eval(string cmd). When you use one of these methods and you do something invaild, it returns a a COMException with a error message and I get the error code from MapInfo. So for example an error message looks like this:
418 "Table not found."
Now I would like to throw some kind of meaning full exception rather then just a exception with a number and message that people have to catch then use a if block to check what error, something they say they only want to catch and do something meaning full with. Something like TableNotFoundException.
The biggest problem is there are currently 1999 possible error messages, now I don't want a exception class for everyone of those errors.
The idea of the SDK is that people use my objects and methods rather then Do and Eval(they can stil use them if they want).
Should I,
everywhere in my SDK that I call Do and Eval use a try catch and then check the error code and throw something more meaning full from there, because I know what errors I should get.
or
I have somekind of God lookup list in the Do and Eval that when a COMException is thrown it lookups the error code and throws the meaningfull error from there? Meaning I don't have to wrap every call to Do and Eval in try catch blocks(there are a lot of calls)
Bit of a tricky thing to explain so I hope people can understand it.
Thanks.
Wrap the calls to Do and Eval in your own function which catches MapInfo errors.
As there are so many error types, you could create an enum with some more descriptive names or a dictionary mapping error numbers to more friendly names (if the original ones aren't good enough) - you don't want 1999 exception classes, so I'd suggest using only one exception class that contains the error number and description. You're saying that users could use Do and Eval directly, so they should know how to handle these error numbers, anyway.
Alternatively, you could create a few hierarchical exception types and decide which one to throw (needs something a dictionary mapping 0-1999 => matching exception type) - that way, users can be a bit more specific about which types of errors to catch.
As per AndiDog, creating a few exception classes that group the couple of thousand errors into some reasonable types. You should probably still pass the original error number out, just in case.
While you're doing that, read this article to sort out how those groups might be assembled, and maybe which ones you DON'T want to catch.

Is it ok to catch all exception types if you rethrow them wrapped another exception?

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.

Best practices for exception management in Java or C# [closed]

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.

Categories

Resources