Dan*_*aft 118

从技术上讲,第一个引发RuntimeError并将消息设置为"foo",第二个引发Exception并将消息设置为"foo".

实际上,在您想要使用前者和何时想要使用后者之间存在显着差异.

简单地说,你可能想要一个RuntimeError不是Exception.没有参数的救援区将会被捕获RuntimeErrors,但不会捕获Exception.因此,如果您Exception在代码中引发一个代码,则此代码将无法捕获它:

begin
rescue
end
Run Code Online (Sandbox Code Playgroud)

为了赶上Exception你必须这样做:

begin
rescue Exception
end
Run Code Online (Sandbox Code Playgroud)

这意味着在某种意义上,a Exception是一个比"更糟糕"的错误RuntimeError,因为你必须做更多的工作才能从中恢复.

所以你想要的取决于你的项目如何处理它的错误.例如,在我们的守护进程中,主循环有一个空白的救援,它将捕获RuntimeErrors,报告它们,然后继续.但是在一两种情况下,我们希望守护进程真的死在一个错误上,在这种情况下,我们会引发一个Exception直接通过我们的"正常错误处理代码"并退出的守护进程.

再说一次,如果你正在编写库代码,你可能想要一个RuntimeError,而不是一个Exception,因为如果它引发了一个空白rescue块无法捕获的错误,你的库的用户会感到惊讶,并且需要花一点时间来实现原因.

最后,我应该说它RuntimeError是类的子StandardError类,而实际的规则是尽管你可以使用raise 任何类型的对象,但是rescue默认情况下,空白只会捕获从中继承的任何内容StandardError.其他一切都必须具体.

  • 非常翔实,谢谢.一些事情:[1]最后一段是最有启发性的,让我在irb发现你没有提到的东西:`RuntimeError <StandardError <Exception` [2]因此,第二段代码_will_同时捕获一个异常和一个RuntimeError [3]有趣/奇怪的是,"裸"加注和救援恰好与特定的异常[4]一起使用,也许经验法则是将RuntimeError提升到客户端代码,但是提升并挽救一个人自己的自定义异常一个人自己的代码? (2认同)

enn*_*ler 33

从官方文档:

raise   
raise( string )
raise( exception [, string [, array ] ] )
Run Code Online (Sandbox Code Playgroud)

没有参数,引发异常$!或引发RuntimeErrorif $!为nil.使用单个String参数,它会将RuntimeError字符串作为消息引发a .否则,第一个参数应该是Exception类的名称(或者返回发送Exception时异常的对象).可选的第二个参数设置与异常关联的消息,第三个参数是回调信息的数组.begin...end块的救援条款可以捕获例外情况.

raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
Run Code Online (Sandbox Code Playgroud)