C# - How to structure error handling in code properly [closed] - c#

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.

Related

What's the best practice to structure exception messages? [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 5 years ago.
Improve this question
When something goes wrong in your program, you can throw an exception in your code with a message that describes a problem. Typical example:
throw new Exception("Houston we have a problem");
Is it a good practice to pass a hardcoded string into an exception constructor? Maybe I should hold all of exception messages in a one place. Please tell me what's the best practice to solve a problem of exception message structuring.
As Tim mentioned in the comments already localization can be a problem if the messages are shown to users.
What my approach on this topic is, and what I really like to suggest is the following.
Try to make it generic.
Makea a constants class holding your exception Messages with meaningfull constants names like this:
public static const String IN_VARIABLE_MISSING = "An expected value is missing. Please try again";
This will give you the ability to actually re-use the exception wherever it is needed. ( Also you only need to edit it at one place and have it updated everywhere ) You can build a wrapper which will handle the localization. But there are so many options for that topic, that I will not elaborate too much.
So you then can throw an exception like this:
throw new Exception(IN_VARIABLE_MISSING);
If this is software which will be used commercial I would also recommend to write an own Exception which extends the standard Exception.
Why?
You can create an exception that will take your message and an number for example and will automatically build an unique key for you like this:
IN-MODULE-NUMBER-IDENTIFICATION
You see where that could be handy? Excactly in localization and in faster finding of where it happened and why it happened.
You can modify it to write IN at the beginning for Internal errors. VA for validation errors. Then the class/project where it happened and then a number or whatever you want.
This system will also give you the ability to use another string for that key depending on the locale the user is using.
TL;DR Make it reusable!
Is it a good practice to pass a hardcoded string into an exception constructor?
Yes and No.
No in the sense that this code:
throw new Exception("Houston we have a problem");
is much harder for the caller to deal with. That's because what the exception means is identified only by the text of the message; therefore a caller wanting to catch exceptions from your code (for example, so as not to crash but continue running if possible) has to make string comparisons to figure out what the problem was.
e.g.
try
{
someService.DoSomething(sessionId)
}
catch(Exception ex)
{
if (ex.Message.Contains("Houston"))
{
//this indicates that someService couldn't connect to the database
}
else if(ex.Message.Contains("is on fire"))
{
//someService detected that the network is exploded
}
else{
//we can only handle the two previous cases, all else is passed on}
throw;
}
As you can see this gets messy fast, and if someone changes the text....
Now this code, on the other hand:
throw new SomethingSpecificWentWrongException(sessionId);
where SomethingSpecificWentWrongException might look like this:
public class SomethingSpecificWentWrongException: Exception
{
public int SessionId {get;protected set;}
public SomethingSpecificWentWrongException(int sessionId):
base($"Something specific went horribly wrong with session {sessionId}")
{
SessionId=sessionId;
}
}
can easily be handled by the caller:
try
{
someService.DoSomething(sessionId)
}
catch(SomethingSpecificWentWrongException ex)
{
//do whatever it is you do to recover from this
}
catch(SomethingElseSpecificWentWrongException wex)
{
//recover from this
}
else
{
throw;
}
You'll notice that there is a hard-coded-ish string here but it's owned by the custom exception class itself, not by the code that decides to throw the exception; this makes a big difference because it means you can guarantee that wherever this exception is used the message is predictable (in terms of logging, etc).
So not only is it easier to reason about, it's a lot more maintainable than hard-coding strings provided by the throwing code.

So is it best to use try/catch? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
When is it best to use try and catch? I've gotten angry responses when I answered questions using try and catch (some even -1 me...) I Googled it and found this article and also this stackoverflow question.
I give some examples:
I have a drop down list with time zone IDs, when the user selects his time zone I'm updating the database. In other application i'm pulling this the value from the DB and recalculate the user current time and date. There is an option that the data in the DB is misspelled (hardcoded change in the DB or bug). In the conversion method of the date time of the user I'm using try and catch, which some people told me it is wrong!. I could check the value from the DB using for loop but it is costing more for each time I'm converting the date time...
I have to declare if an XML file is well formatted using this code:
protected bool IsValidXML(string xmlFile)
{
try
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlFile);
}
catch(XmlException ex)
{
///write to logger
return false;
}
return true;
}
I can't see any other way to check the xml file.
Sometime I have a part on my application I'm writing to a file. writing to a file can cause exeprtion for many reasons , some other process is using this file while writing or other. so usually I'm using this code:
using (StreamWriter w = new StreamWriter(fs))
{
try
{
w.Write("** (Line) " + someValue + " **" + Environment.NewLine);
w.Flush();
}
catch(IOExeption ex){}
finally
{
w.Close();
}
}
In conclusion I see some ways to use try and catch and ways to not use. The one sentence in the article I saw said If an exception happens, you need to know about it. , but when dealing with a generic application most of the times I know that an exception will happened but most of the times I can't really know why it happened so I can't catch it before (like the examples I wrote) , So when is best to use the try and catch
In the same level in ASP.NET the page has an Error event that you can catch like so:
this.Error += new EventHandler(Page_Error); //this = instance of System.Web.UI.Page
Is the event is the same as try catch problem??
How you handle an exception depends on the nature of the exception, and on the context in which it occurs.
Smart people have written excellent articles about the subject, and I certainly can recommend:
How to Design Exception Hierarchies by Krzysztof Cwalina
Vexing exceptions by Eric Lippert
API Design Myth: Exceptions are for "Exceptional Errors" by Krzysztof Cwalina
About your examples:
In case 1 you might indeed want to be defensive. But then make sure that you do something sensible in that catch block.
Case 2 looks reasonable, but you're reading the XML document only to throw it away. Would it no make more sense to also process it?
In Case 3 you are using try finally, which is definitely not the same thing as try catch. In your specific example you don't even need it, as the using statment is already making sure the file will be closed.
From a personal perspective I've always assumed that whatever can go wrong, will go wrong and write my exception handling strategy accordingly. One of my major bugbears with others code is when you get an unhandled exception that could easily have been trapped - it looks messy an if it is production code then it shows a complete lack of knowledge of how your program works and the things that might go wrong.
My approach might be overkill, but if something you are doing can throw an error then it should be trapped. I'm not a huge fan of letting exceptions cascade through the stack and being caught at the top level - I'd prefer to trap them at source, log them and then, if the application allows it continue, or at worst fail gracefully and leave the user (or other developers) understanding what has gone wrong or why.
With web applications we use a slightly different approach. The error (stack trace etc) is logged, so that authorised people can see it and the user is given a cut-down version of the error which tells them something has gone wrong but not the specifics.
Thats my two pence anyway. I'm not sure if the approach is right or wrong, but it works for us and helps us to produce more robust code.
The criticisms of your use of try/catch in this answer were not against using try/catch in general, but against that particular way of using it.
You should capture the exception object (i.e. use catch(SomethingHappenedException e) so you get the available information about what went wrong.
You should catch specific exceptions rather than everything. In the DateTime example, I would try to find what exceptions might be thrown by each of my calls. I would then try and figure out if there was some way of trapping these errors without using exceptions - one of the exceptions that might be caught in that code is a ArgumentNullException. That's an exception, but I should be able to handle that within the flow by first checking that I'm not passing a null zone id.
Finally, if it's not possible to handle those cases within the normal flow of the program, I catch specific exceptions that might plausibly occur, and as closely to the source of the exception as possible.
It might seem a bit more effort but it does save you on debugging time down the road!
For example 1, it would be helpful to see code. It's hard to comment without a more concrete idea of what you're doing.
For example 2, the problem with that code is that it completely hides any error condition. Sure, we'll find out if an xml file is good or bad... but why is the xml good or bad? We can't know. It's not that try/catch is bad: it's that the whole thing is being written at the wrong level. Just write code to read the xml file, and have your error handling around that code.
For example 3, you are again swallowing any helpful exception information, and in fact not doing anything with your try/catch at all. The .Close() call in your finally blocks is completely unecessary, because closing your stream is entirely handled when the stream is disposed by the using block.
In summary, I think what you need to learn here is not that try/catch blocks are bad. It's that swallowing exception information is bad.
I think I can sum up the issues people have had in the past with your questions on try...catch, as well as provide some clarity that should help you in the future.
Your first two examples are caused by data validation errors. The data should be checked for known validation errors before being passed to the conversion function (example 1) or trying to write an XML file (example 2).
There is significant overhead in exception handling, so it should only occur when absolutely necessary. The try...catch pattern is designed for handling unexpected (exceptional) errors, not standard data validation.
Example 3 is almost proper usage. It is a situation where there are unexpected things that may occur that you cannot be prepared for, like an IOException. Catching a specific exception is considered bad form as it can lead to multiple catch blocks or missed handling. Catching the generic Exception object is better, and the exception handling code can determine and deal with the exact type of exception.
Your try...catch block should encapsulate the streamwriter as well, since it is best practice to only have one try...catch per method. If you use try...catch, it must always contain exception handling code. Empty catch blocks or empty finalize blocks are bad form and are not helping the code or anyone who is trying to maintain it after you.
try
{
using (StreamWriter w = new StreamWriter(fs))
{
w.Write("** (Line) " + someValue + " **" + Environment.NewLine);
w.Flush();
}
}
catch(Exception ex)
{
//exception handling code here
}
finally
{
//any clean up code here. The using statement makes it unnecessary for the streamwriter
}
Hope all of this helps answer some questions and bring some clarity to the issue.
In my experience, any external operations (such as interacting with a db or file system, or using 3rd party components) should have a try catch block around it. In my own code, I always try to put in guard clauses to methods to limit the number of exceptions my own code produces, if for example you know that the database won't accept a null First name on a person object, add a guard clause should be added to the top of any save method.
In short, don't rely on exceptions to tell you where your code is going wrong, rather try to cut down the likelyhood of an exception first

Correct way to document bubbled exceptions in 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 5 years ago.
Improve this question
Below is a simplified example of a setup I have. My issue is an exception is thrown at a low level which will then bubble up. However, classes at a higher level do not know what horrors await them when they use the lower level class functions. By this I mean developers will come along and use Class3.DoWork3() without any exception handling for the dreaded 'MyCustomException'.
Am I approaching this all wrong? I don't want to catch and throw the same exception multiple times (I have no need to do any kind of clean up for example in Class2).
public class Class1
{
<exception cref="MyCustomException">description</exception>
public void DoWork1()
{
throw new MyCustomException("I have failed you class1.");
}
}
public class Class2
{
public void DoWork2()
{
var classOne = new Class1();
// Here I can see that DoWork1() will throw a 'MyCustomException'
classOne.DoWork1();
}
}
public class Class3
{
public void DoWork3()
{
var classTwo = new Class2();
// I can no longer see that Class2.DoWork2() will throw a 'MyCustomException'
classTwo.DoWork2();
}
}
In order to clear up some confusion which seems to have been generated in the comments I will put the two solutions which I am considering at present:
Tag DoWork2 with the same MyCustomException comment as Class1
Throw a different exception within DoWork2 and tag it with this
new exception. This option seems the most robust as it would allow a
more detailed log (e.g. where exactly the code fell over in it's
execution path). This way does seem a little over the top for
simplistic scenarios which is why I wonder if (1) is an acceptable
solution to this problem?
One of the major limitations with exception handling in .NET and Java is that there's no standardized means by which code can distinguish between an exception of some type which is thrown from a method for reasons that method expects, versus an exception of that same type which is thrown by a nested method, for reasons the outer method did not expect. If the purpose of a method is to call some user-supplied delegate, the only ways I know of to reliably distinguish between exceptions which are thrown by the called delegate and those which occurred in the process of calling it are either to pass the method an identity token which it will include in any exceptions it throws directly, or else have the method as a matter of policy wrap exceptions that occur while invoking the user-supplied callback. Neither method is terribly elegant.
Because there is no standardized way to identify exceptions which indicate that an operation failed "cleanly" without side-effects, from those which indicate that a more serious problem exists, I would suggest that code shouldn't rely upon "serious" exceptions to prevent "contagious" data corruption. Instead, any time an exception might cause an object to be left in a corrupt state, the object should be explicitly invalidated, to prevent corrupt data from being read from it and copied elsewhere (possibly overwriting what would have been the only good copy). In situations where the corrupted object isn't needed and stack unwinding would cause it to be invalidated, there is no problem. In situations where the object that was invalidated turns out to be essential for system operation, the program should be forcibly shut down and invalidating the object will make that happen more reliably than would throwing a "serious" exception.
Unfortunately, neither C# nor VB.NET provides a very nice pattern for guarding objects in this fashion. VB.NET has somewhat better exception-handling abilities than C#, and the correct pattern (taking action in a finally block based upon what exception was thrown, but without catching the exception) can be implemented, albeit awkwardly, in that language. In C# the only way to find out what exception occurs within a try block is to catch and rethrow, an action which has some side-effects.
There is an excellent interview with Anders Hejlsberg titled The Trouble with Checked Exceptions. (Anders led the team that designed the C# programming language.)
You are falling into the exception aggregation trap. You should probably not be asking "what exceptions could possibly be thrown by lower level systems?" The answer, in many cases, would be a list containing hundreds of unique exceptions.
Instead, you should ask yourself "how can I provide useful information to the developer?" You should document the exceptions that your code is explicitly throwing or, in rare cases, relevant exceptions that are very likely to occur and that the caller may be specifically interested in. The developer who calls your code can determine the necessity of handling those errors or passing that information along to the callers of their code - or simply doing nothing with it. Exceptions are exceptional, after all, and at a certain level it doesn't really matter which database error was thrown - the steps taken in response are the same (e.g. stabilize the environment if possible, write to the error log and terminate execution).

Try catch inside or out? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What's better and why:
This
public void Main()
{
SomeMethod();
}
public void SomeMethod()
{
try
{
// code
}
catch(Exception)
{
}
}
or this:
public void Main()
{
try
{
SomeMethod();
}
catch(Exception)
{
}
}
The answer is: "catch the exception at the lowest level that knows how to handle it."
There is a idea that you should be catching exceptions closest to where they occur (i.e. as high up the call stack as possible/appropriate). A blanket exception handler isn't typically a good idea because its drastically reduces the control flow available to you. Coarse-grained exception handling is quite importantly, but not a reasonable solution to program stability. Unfortunately, many beginner developers think that it is, and take such approaches as this blanket try-catch statement.
Saying this, if you have utilized exception handling properly (in a fine-grained and task-specific manner) in the rest of your program, and handled the errors accordingly there (rather than just displaying a generic error box), then a general try-catch for all exceptions in the Main method is probably a useful thing to have. One point to note here is that if you're getting bugs caught in this Main try-catch, then you either have a bug or something is wrong with your localized exception handling.
The primary usage of this try-catch with Main would be purely to prevent your program from crashing in very unusual circumstances, and should do hardly any more than display a (vaguely) user-friendly "fatal error" message to the user or just be left blank, as well as possibly logging the error somewhere and/or submitting a bug report.
Credits: Noldorin
See Exceptions and Exception Handling (C# Programming Guide) for guidance on exception handling in C#. This interview with Anders Hejlsberg is also informative.
The relevant guideline here is:
Do not catch an exception unless you can handle it and leave the application in a known state.
Generally, an exception should not be caught unless it can be properly handled. This could be either Main or SomeMethod, depending on what is coded. For instance, Main might include a general catch statement to handle general exceptions (and, for instance, write an error message to the console); but SomeMethod might be able to recover from certain exceptions and catch those.
Generally, catch {} (exception swallowing) should be avoided; a caller that cannot handle an exception should simply allow it to propagate upward.
There is no rule about which one is better. You can use both methods. The deal is you need to have the code that is most likely to throw an exception inside try and this applies to all programming language.
Let say the next happens:
You want a valid message for each failure.
public void Main()
{
try
{
SomeMethod();
}
catch(Exception)
{
}
}
The above will be less informative, than catching each try inside SomeMethod(), so even so there is no difference, I will suggest to catch small actions that might fail, to provide useful data about the cause of the error.
In my opinion you catch the exception in SomeMethod before it goes above and might get lost due to no immediate code visibility on the eyes
One very important thing is please try to catch the specific exception first rather than anything
e.g.
if SomeMethod is doing some string to number conversion then try to catch FormatException first and put the Exception class for anything else
I think, customizing will be the best way to throw more understandable exceptions at the lowest level.
first define your custom exception class
public class SomeException : Exception {}
public void SomeMethod()
{
try
{
// code
}
catch(Exception e)
{
throw new SomeException ("an error in somemethod",e);
}
}
now, you will catch more clearly exception at anywhere.

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