What is the difference - technical, philosophical, conceptual, or otherwise - between
raise "foo"
and
raise Exception.new("foo")
?
Technically, the first raises a RuntimeError with the message set to "foo"
, and the second raises an Exception with the message set to "foo"
.
Practically, there is a significant difference between when you would want to use the former and when you want to use the latter.
Simply put, you probably want a RuntimeError
not an Exception
. A rescue block without an argument will catch RuntimeErrors
, but will NOT catch Exception
s. So if you raise an Exception
in your code, this code will not catch it:
begin
rescue
end
In order to catch the Exception
you will have to do this:
begin
rescue Exception
end
This means that in a sense, an Exception
is a "worse" error than a RuntimeError
, because you have to do more work to recover from it.
So which you want depends on how your project does its error handling. For instance, in our daemons, the main loop has a blank rescue which will catch RuntimeErrors
, report them, and then continue. But in one or two circumstances, we want the daemon to really really die on an error, and in that case we raise an Exception
, which goes straight through our "normal error handling code" and out.
And again, if you are writing library code, you probably want a RuntimeError
, not an Exception
, as users of your library will be surprised if it raises errors that a blank rescue
block can't catch, and it will take them a moment to realize why.
Finally, I should say that the RuntimeError
is a subclass of the StandardError
class, and the actual rule is that although you can raise
any type of object, the blank rescue
will by default only catch anything that inherits from StandardError
. Everything else has to be specific.