Don’t Use Try/Catch (2010)
codebetter.com
codebetter.com
The author raises the interesting point that if it's truly an exception, you're better off letting the system crash all together (especially in a webapp, where you're basically dropping a single request for a single user) -- and if it's an "expected exception", then you should be handling it directly.
I don't see how that reduces to "never use try/catch" though, since catching a specific exception (or types of exceptions) is a way of "handling it directly."
There will be cases where you want to do "catch {}" — you don't always have control over the exceptions thrown by a lower-level library. It might be good to create a standard where you log them conditionally, or something that could aid in troubleshooting.
It's been best practice for quite some time not to catch { // heh heh he. }.
Nothing about catch requires the program to continue executing as though no exception ever happened, many catches can be fatal but handle emergency cleanup.
If an application crashes on Windows due to an exception, it can be picked up by Microsoft's Watson error logging (now called Windows Error Reporting, I believe). If the user has marked the checkbox "help Microsoft improve Windows by sending crash information" then the dump of the application will be sent to a central location, where it can be triaged and accessed by the application's developer.
Now instead of just a generic entry in a log file, you have a full memory dump of the exception.
Yes, I did include a "this never happens" comment. That is my favorite comment, but only if it is true.
Don't leave empty catch blocks. At least put in some form of logging of the exception, just in case.
default:
throw new InvalidOperationException("Should never happen!");The author is right that your code needs to properly react to exceptions and not swallo them. . A global exception handler lets you report to all exceptions, but in order to give proper feedback to the user you definitely have to catch exceptions elsewhere in the code.
Of course, you should be judicious in your usage of try/catch, since it's obviously something that can be abused very poorly.
Reminds me of when I was trying to write a Win8/Metro app for fun. Turns out in the particular network class I was using 404's throw exceptions. What a horrific design - 404 isn't an unexpected state at all, particularly when calling restful apis. But there we were, a pointless try/catch or nothing.
A lot of the brokenness with exceptions is software that models expected operational state as exceptions.
try { setTimeout(foo, 1000) } catch (ex) { ... }
won't be caught here if foo throws. In some DOM APIs there are 'onerror' handlers (like XHR), in NodeJS the convention is to have an "error" first parameter in the callback (which is null if there's no error).
Also try-catch generates additional scope object inside the catch clause hence it's a bit more expensive than just doing a function call.
Generally try-catch makes sense in JavaScript only locally when executing some external synchronous code that is known to throw exceptions.
I've had... I think it was Windows::UI::Input::PointerPoint::GetCurrentPoint throw exceptions if the finger passed in was no longer touching the screen. Sounds fine at first, right? Except...
1) This occurred before "finger released" events, so you'd run into a crash because they thought throwing an exception was better than returning the last known finger position, which would've rightly left me with no error report.
2) This occurred in a nasty rare corner case, making figuring out the reproduction a PITA. I don't think I'm alone in not expecting such a simple function to throw when given a known-to-me-valid fingerId. Worse, the exception was completely undocumented on MSDN -- either explicitly or as a hint from function signature (at least Win32 had the common decency to return BOOL or HRESULT.)
3) I found no method for validating a finger ID, so one had to simply catch the exception and accept the massive framerate dip of exception handling overhead if the user pawed at the screen. Before you mistake that for hyperbolic performance concerns: I could make a smooth 30fps tank to bellow 10fps consistently. I measured!
Touch input isn't the only unexpected thing throwing exceptions for WinRT. The end result of this "throw exceptions whenever you can" mentality is I've been forced to build a habit of wrapping every WinRT API call in extremely wide try/catch blocks to log whatever random undocumented exceptions come crawling out of it. By becoming the rule, it took the "exception" out of "exceptions". I'm sure you'll agree: This is horrifically ugly, slow, and in generally poor taste.
But it's necessary. The other alternative is you hopefully find as many as 90% of the weird junk that crashes your program with exceptions, most of which you don't actually care about in the slightest -- and the other 10% avoid discovery and instead explode your stuff in production, most of which will be for no good reason.
Exceptions, as the name itself indicates, should only be reactions to EXCEPTIONAL situations. Showstoppers.
The adage is: don't use exceptions for flow control. In the case you described, it seems to me that they did just that, and I don't condone that. It's clearly a case of bad, or at least unfortunate API design...
By "whenever you can" I meant "whenever you can once the ground criteria are met", I kind of thought it goes without saying but I should've been more precise
except SomeException as exception:
raise NewException("stuff happened") from exception
1) http://www.python.org/dev/peps/pep-0415/