Related
When we wrap a bunch of statements in a try/catch and one of these issues an exception, within the catch we have no way of knowing which of the statements caused the exception (the ex.stacktrace shows our current method (doit), its caller, its caller's caller, etc. but neither do1 or do2):
function doit() {
try {
do1();
do2();
[...]
}
catch (Exception ex) {
// what failed?
}
}
generally I've taken to wrapping all statements and rethrowing, sort of like:
private void do1() {
try {
// do whatever
} catch(Exception e) {
// write to my error log
throw new Exception("do1: " + e.Message, e.InnerException);
}
}
which leaves a trail of breadcrumbs in my log and makes the chain available for the upstream. The problem, of course, is that I have to wrap every method I write with this kind of code.
something tells me I'm being dumb about it. what is the right approach?
Ok, this is hard to get right because exception handling is a really really touchy subject and in the past people have fought religious wars over how to do this right.
First off: neither use an empty catch (try { ... } catch { ... }), nor catch(Exception ex).
The sole purpose of Exception-derived classes is to give you rich information about the kind of exception which occured so you can do something meaningful in your exception handler (if a thread crashed restart it, if a db connection failed non-permanently try again, then fail, etc).
People tend to use a catch-all handler for the outermost part of their code to log uncaught exceptions and this is kind of OK, but in any case you should either prompt the user or rethrow the exception (using throw, not throw ex - there is a ton of discussion about this as well).
Basically you do not programmatically care about where the Exception occured at all.
You can either handle it or you can't. If you can't handle it then you don't catch it.
Addendum: The most important reason for this "if you can do something about it, do so, otherwise dont you dare touch that exception" philosophy is that silently caught exceptions (whether logged or not) can lead to really hard-to-find bugs. Just pushing them out to a logfile might not be enough because in a live system you may not get the fully annotated stack trace (with line numbers and everything).
Addendum 2: Take for instance a textbox which expects an integer input. If the user supplies a string you cannot meaningfully process the input, maybe a conversion exception gets thrown, you catch that specific exception and reset the textbox to its old value and maybe inform the user about the erroneous input. Alternatively your program might either just die with an exception (bad design, you could recover from that exception) or silently go on showing the erroneous input, but still using the old value (bad design, the program is misleading).
If you are really sold on doing this (others have stated why this is bad already), use an Aspect Oriented Programming approach. This will make your life significantly easier and reduce the amount of code you end up writing and maintaining.
Take a look at PostSharp, it gives you a framework that allows you to decorate methods, classes, or namespaces with attributes that will generate this boilerplate error handling for you.
#Branko nailed it in the comments: the exception's stack trace shows the point where the exception was thrown, not where it was caught.
+1 for #ChaosPandion's comment: this is a very, very, very bad idea.
try and catch seem to me to be probably the single worst designed modern programming mechanism. We no longer have the ability to handle errors as we go; we must fail the entire procedure if a single exception occurs, unless we do something horrifying like try every statement individually. There is no longer the option of recovering, only failing as gracefully as possible.
The best pattern for this I have found so far is to wrap every user event in a try/catch (using a method, not an explicit try every time). Ex:
public static class Defines
{
public static bool TryAction(Action pAction)
{
try { pAction(); return true; }
catch(Exception exception) { PostException(exception); return false; }
}
}
...
private void DoSomething(int pValue)
{
...
}
private void MyControl_MyEvent(object pSender, MyEventArgs pEventArgs)
{
Defines.TryAction(() => DoSomething(pEventArgs.Data));
}
Beyond that, just try to write exception-less code. Only use explicit trys when you are very likely to get an exception and want to do a little more than just fail gracefully.
I've got a new project. Every time you dealing with somebody else code it's an adventure.
Here is what I found:
try
{
.....
}
catch (InvalidOperationException e) {
throw e;
}
catch (Exception e)
{
throw;
}
Anybody has an idea why?
PS
Thanks everybody.
It really helps.
Here are some good sources that you recommended:
Why catch and rethrow an exception in C#?
http://msdn.microsoft.com/en-us/library/0yd65esw.aspx
http://msdn.microsoft.com/en-us/library/ms229005.aspx
Because whoever has written this doesn't have any understanding of how exceptions work in .NET.
If you don't do anything with an exception, don't catch it.
The code you posted would better be written as:
.....
The real danger of this (other than being completely useless...) is that it modifies the call stack. Others have briefly mentioned it in comments, but it deserves to be called out specifically.
When you have throw ex;, the previous call stack is blown away and replaced with the call stack at the point where throw ex; is called. You almost never want to do this. I will often catch an exception, log it, then rethrow the exception. When doing that, you want to just use throw;. This will preserve the original stack trace.
Makes no sense whatsoever to me, but not for the reason you might think.
Catching an exception is not the same thing as handling it. This try/catch block does no handling at all. I think a better, more honest, less verbose solution would have been to remove the try/catch and let the exceptions bubble up to where they can/should be dealt with.
i guess the application wants the outer method calling this to catch the exception instead but this is not the way it should be done, do check these references as they are somewhat similar
Why catch and rethrow an exception in C#?
http://winterdom.com/2002/09/rethrowingexceptionsinc
It is possible that they wanted to implement different handling for InvalidOperationException and other types of exceptions, so they wrote this code as a stub. But then this idea was abandoned so you see this code artifact.
you can improve this code by adding logging.
after every catch, log the information that you throw.
there are some opensource code available for logging.
As all of you probably know, catching and re-throwing a exception in c# this way is evil, because it destroys the stack trace:
try
{
if(dummy)
throw new DummyException();
}
catch (DummyException ex)
{
throw ex;
}
The right way to re-throw an exception without loosing the stack trace is this:
try
{
if(dummy)
throw new DummyException();
}
catch (DummyException ex)
{
throw;
}
The only problem with this is that I get a lot of compilation warnings: "The variable 'ex' is declared but never used". If you have a lot of these, a useful warning may be hidden in the garbage. So, that's what I did:
try
{
if(dummy)
throw new DummyException();
}
catch (DummyException)
{
throw;
}
catch(AnotherException ex)
{
//handle it
}
This seems to work, but I'd like to know if there is any downside of re-throwing an exception that is not set to an variable. How does .net threats this?
Thanks in advance
Edit:
I've changed my code a little bit to make clearer what I wanted to do, as some had misunderstood
I'd like to know if there is any downside of re-throwing an exception that is not set to an variable.
No, there's no downside at all. A variable is only needed if you want to reference the exception in your code, but since you don't need to do that with a throw statement, you don't need a variable at all.
And you have exactly the right idea in attempting to eliminate "noisy" compiler warnings. They have a tendency to bury important errors that you do want to fix, and getting a clean build is always important. The best solution is simply to rewrite the code to use a parameterless catch clause.
However, be aware that in 82% of cases that I see*, it's a mistake to write code that uses throw at all. You generally shouldn't catch exceptions that you don't know how to handle and your only intended "handling" strategy is to rethrow them. There are cases where even using throw can reset the call stack, causing you to lose important debugging information. There are also better alternatives for logging exceptions to catching/rethrowing. You can find more information in the answers to these questions:
Main method code entirely inside try/catch: Is it bad practice?
what can lead throw to reset a callstack (I'm using "throw", not "throw ex")
There's absolutely nothing wrong with letting exceptions bubble up and handling them all in a central place. The rule to keep in mind is that you shouldn't use exceptions for flow control. But there's nothing wrong with throwing an exception in low level code, and showing the user an error message higher up the stack in UI code. Read Microsoft's Best Practices for Handling Exceptions for some general tips.
* Slightly more than the percent of statistics that are made up on the spot.
There is no downside to that. You are simply telling the compiler "I plan to catch this exception but I have no need for a reference to the actual exception", it doesn't affect how things are thrown or how exceptions work. Your latter example is the ideal way to do what you want, however if you are merely going to immediately throw; with nothing else whatsoever in the block, then why catch at all?
If you're not doing anything with DummyException in the catch block (which you can't, since you haven't given it an identifier), why not get rid of the try/catch block entirely? E.g., just do this:
throw new DummyException();
Although at that point, I'd probably evaluate what you're trying to accomplish here and rethink your application architecture so as not to not rely on exception propagation in this manner.
Why catch if your simply going to re-throw? Anyway, you may want to take a look at this previous discussion. Though not identical much of what is discussed is relevant:
Throw VS rethrow : same result?
Actually throwing an exception using "throw;" is a .Net best practice, because it preserves exception stack trace.
Throwing exceptions using "throw ex;" is considered a worst practice, because it looses the original stack trace and should be avoided.
Why catch and rethrow like this? Why do people always have to assume they know every case? Answer: Database transactions.
If you have a better way to do this please speak up Dr. Proton, no offense taken. Keep in mind that there are a lot of different database systems in use but most of them support transaction control (begin/commit/rollback) and have C# interfaces.
pseudocode (a simplified case):
try
{
db.beginTrans();
db.doStuff();
db.doOtherStuff();
db.commitTrans();
}
catch
{
db.rollbackTrans();
throw;
}
Now, it is quite annoying to lose the detail of whether doStuff() or doOtherStuff() failed and I don't see any good reason why C# would toss the line number information in this case. But it seems to. Hence the googling and my subsequent arrival. If I am missing something please do tell.
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
Sometimes I do this and I've seen others doing it too:
VB:
Try
DontWannaCatchIt()
Catch
End Try
C#:
try
{
DontWannaCatchIt();
}
catch {}
I know I should catch every important exception that I'm expecting and do something about it, but sometimes it's not important to - or am I doing something wrong?
Is this usage of the try block incorrect, and the requirement of at least one catch or finally block an indication of it?
Update:
Now I understand the reason for this, and it's that I should at least comment on the empty catch block so others understand why it's empty. I should also catch only the exceptions I'm expecting.
Luckily for me I'm coding in VB so I can write it in just one catch:
Catch ex As Exception When TypeOf ex Is IOException _
OrElse TypeOf ex Is ArgumentException _
OrElse TypeOf ex Is NotSupportedException _
OrElse TypeOf ex Is SecurityException _
OrElse TypeOf ex Is UnauthorizedAccessException
'I don't actually care.
End Try
If you don't want to catch it, why are you using try in the first place?
A try statement means that you believe something can go wrong, and the catch says that you can adequately handle that which goes wrong.
So in your estimation:
try
{
//Something that can go wrong
}
catch
{
//An empty catch means I can handle whatever goes wrong. If a meteorite hits the
//datacenter, I can handle it.
}
That catch swallows any exceptions that happen. Are you that confident in your code that you can handle anything that goes wrong gracefully?
The best thing to do (for both yours and your maintenance programmer's sanity) is to explicitly state that which you can handle gracefully:
try
{
//Something that could throw MeteoriteHitDatacenterException
}
catch (MeteoriteHitDatacenterException ex)
{
//Please log when you're just catching something. Especially if the catch statement has side effects. Trust me.
ErrorLog.Log(ex, "Just logging so that I have something to check later on if this happens.")
}
No, you should not catch every important exception. It is okay to catch and ignore exceptions you don't care about, like an I/O error if there's nothing you can do to correct it and you don't want to bother reporting it to the user.
But you need to let exceptions like StackOverflowException and OutOfMemoryException propagate. Or, more commonly, NullReferenceException. These exceptions are typically errors that you did not anticipate, cannot recover from, should not recover from, and should not be suppressed.
If you want to ignore an exception then it is good to explicitly write an empty catch block in the code for that particular exception. This makes it clear exactly what exceptions you're ignoring. Ignoring exceptions very correctly is an opt-in procedure, not an opt-out one. Having an "ignore all exceptions" feature which can then be overridden to not ignore specific types would be a very bad language feature.
How do you know what types of exceptions are important and should not be caught? What if there are exceptions you don't know about? How do you know you won't end up suppressing important errors you're not familiar with?
try
{
}
// I don't care about exceptions.
catch
{
}
// Okay, well, except for system errors like out of memory or stack overflow.
// I need to let those propagate.
catch (SystemException exception)
{
// Unless this is an I/O exception, which I don't care about.
if (exception is IOException)
{
// Ignore.
}
else
{
throw;
}
}
// Or lock recursion exceptions, whatever those are... Probably shouldn't hide those.
catch (LockRecursionException exception)
{
throw;
}
// Or, uh, what else? What am I missing?
catch (???)
{
}
No catch or finally is invalid. Empty catch or finally is valid. Empty catch means you don't care about exceptions, you just try to do something and it doesn't matter if it doesn't work, you just want to go on. Useful in cleanup functions for example.
Also if you haven't to do something about an error maybe you should specify what kind of exception the program has to ignore.
If you have to ignore every exception, I can't see why you can't use try/catch in this way.
It's usually a mistake. Exceptions signal, well, exceptional behavior; when an exception is thrown it should mean that something went wrong. So to continue normal program flow as if nothing went wrong is a way of hiding an error, a form of denial. Instead, think about how your code should handle the exceptional case, and write code to make that happen. An error that propagates because you've covered it up is much harder to debug than one that surfaces immediately.
It's not made easy for you to do because it's considered bad practice by the majority of developers.
What if someone later adds a method call to the body of DontWannaCatchIt() that does throw an exception worth catching, but it gets swallowed by your empty catch block? What if there are some exceptions that you actually would want to catch, but didn't realize it at the time?
If you absolutely must do this, try to be as specific as possible with the type of exception you're going to catch. If not, perhaps logging the exception is an option.
An error exists, has been thrown, and needs to go somewhere. Normal code flow has been aborted and the fan needs cleaned.
No catch block = indeterminate state. Where should the code go? What should it do?
An empty catch block = error handled by ignoring it.
Note: VBA has a vile "On Error Continue"...
The reason I've heard is that if your try fails for ANY reason, giving you control of the error response is highly preferable to giving the Framework control of it, i.e., yellow screen or error 500.
what if you write only code with try
try
{
int j =0;
5/j;
}
this would equivalent to write
int j =0;
5/j;
so writing try does not make any sense , it only increse your count of lines.
now if you write try with empty catch or finally , you are explicitley instructing runtime to behave differently.
so that' why i think empty try block is not possible.
Yes, it is incorrect. It's like goto: one per 100 KLoc is fine, but if you need many of these, you are doing it wrong.
Swallowing exceptions without any reactions is one of the worse things in error handling, and it should at least be explicit:
try
{
DontWannaCatchIt();
}
catch
{
// This exception is ignored based on Spec Ref. 7.2.a,
// the user gets a failure report from the actual results,
// and diagnostic details are available in the event log (as for every exception)
}
The further-away-look:
Error handling is an aspect: in some contexts, an error needs to be thrown and propagate up the call stack (e.g. you copy a file, copy fails).
Calling the same code in a different context might require the error to be tracked, but the operation to continue (e.g. Copying 100 files, with a log indicating which files failed).
Even in this case, an empty catch handler is wrong.
With most languages, there is no other direct implementation than to try+catch within the loop, and build the log in the catch handler. (You could build a mroe flexible mechanism, though: Have a per-call-thread handler that can either throw, or stow away the message. However, interaction with debugging tools suffers without direct language support.)
A sensible use case would be implementing a TryX() from a X(), but that would have to return the exception in question.
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.