Answers:
从技术上讲,第一个引发消息设置为的RuntimeError,"foo"
第二个引发消息设置为的Exception "foo"
。
实际上,何时使用前者和何时使用后者之间存在显着差异。
简而言之,您可能希望RuntimeError
不要使用Exception
。没有参数的救援块将捕获RuntimeErrors
,但不会捕获Exception
s。因此,如果您Exception
在代码中引发,则此代码将无法捕获它:
begin
rescue
end
为了赶上Exception
您,您将必须执行以下操作:
begin
rescue Exception
end
从某种意义上讲,这意味着a Exception
比a是“更糟糕”的错误RuntimeError
,因为您必须做更多的工作才能从中恢复。
因此,您要取决于项目的错误处理方式。例如,在我们的守护程序中,主循环有一个空白的救援程序,它将捕获RuntimeErrors
,报告它们,然后继续。但是在一种或两种情况下,我们希望守护程序确实真的因错误而死亡,在那种情况下,我们引发一个Exception
,它直接通过我们的“常规错误处理代码”来回。
再说一次,如果您正在编写库代码,则可能需要一个RuntimeError
,而不是一个Exception
,因为库用户会因出现空白rescue
块无法捕获的错误而感到惊讶,并且花了一些时间才意识到原因。
最后,我应该说RuntimeError
是类的子StandardError
类,实际规则是,尽管您可以使用raise
任何类型的对象,但rescue
默认情况下,空白将仅捕获从继承的任何内容StandardError
。其他所有内容都必须具体。
StandardError
。它不一定要比的几行更复杂class MissingArgumentsError < StandardError; end
。
raise
raise( string )
raise( exception [, string [, array ] ] )
不带参数的情况下,在中引发异常,$!
或者引发RuntimeError
if $!
is nil。仅使用单个String
参数,它将RuntimeError
使用字符串作为消息引发a 。否则,第一个参数应该是Exception
类的名称(或返回发送Exception
时异常的对象)。可选的第二个参数设置与异常关联的消息,第三个参数是回调信息数组。例外由以下内容的救援条款捕获:begin...end
块。
raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
RuntimeError < StandardError < Exception
[2]因此,第二段代码将同时捕获Exception和RuntimeError [3]有趣/奇怪的是,“裸露”的引发和挽救恰好与特定的Exception [4]一起使用,也许经验法则是将RuntimeError引发给客户端代码,但是在自己的代码内部引发和挽救自己的自定义Exception?