Ryan Davis’s Ruby QuickRef says (without explanation):
Don’t rescue Exception. EVER. or I will stab you.
Why not? What’s the right thing to do?
Because this captures all exceptions. It's unlikely that your program can recover from any of them.
You should handle only exceptions that you know how to recover from. If you don't anticipate a certain kind of exception, don't handle it, crash loudly (write details to the log), then diagnose logs and fix code.
Swallowing exceptions is bad, don't do this.
All of these can be shown by running this program, and trying to CTRLC or
does not rescue from
If you have a situation where you do want to rescue from
which is equivalent to:
One of the few common cases where it’s sane to rescue from
That's a specific case of the rule that you shouldn't catch any exception you don't know how to handle. If you don't know how to handle it, it's always better to let some other part of the system catch and handle it.
The real rule is: Don't throw away exceptions. The objectivity of the author of your quote is questionable, as evidenced by the fact that it ends with
Of course, be aware that signals (by default) throw exceptions, and normally long-running processes are terminated through a signal, so catching Exception and not terminating on signal exceptions will make your program very hard to stop. So don't do this:
No, really, don't do it. Don't even run that to see if it works.
However, say you have a threaded server and you want all exceptions to not:
Then this is perfectly acceptable in your connection handling thread:
The above works out to a variation of Ruby's default exception handler, with the advantage that it doesn't also kill your program. Rails does this in its request handler.
Signal exceptions are raised in the main thread. Background threads won't get them, so there is no point in trying to catch them there.
This is particularly useful in a production environment, where you do not want your program to simply stop whenever something goes wrong. Then you can take the stack dumps in your logs and add to your code to deal with specific exception further down the call chain and in a more graceful manner.
Note also that there is another Ruby idiom which has much the same effect:
In this line, if
Generally, don't do that, except in special cases where you know you don't need to worry. One example:
Let's say you are in a car (running Ruby). You recently installed a new steering wheel with the over-the-air upgrade system (which uses
You are on a bridge, and realize you are going a bit towards the railing, so you turn left.
oops! That's probably Not Good™, luckily, Ruby raises a
The car should stop immediately - right?
You notice something is wrong, and you slam on the emergency breaks (
Yeah - that didn't help much. You're pretty close to the rail, so you put the car in park (
At the last second, you pull out the keys (
Hopefully you have insurance (Backups). Oh yeah - because the airbag didn't inflate, you're probably hurt (getting fired, etc).
But wait! There's
Let's say you're that car, and you want to make sure the airbag inflates if the car is going more than 5mph before stopping.
Here's the exception to the rule: You can catch
But adding rescue is both easy to forget in a language like Ruby, and putting a rescue statement right before re-raising an issue feels a little non-DRY. And you do not want to forget the
Thankfully, Ruby is awesome, you can just use the
Boom! And that code should run anyways. The only reason you should use
This will also hide bugs from you, for example if you mistyped a method name: