`raise“foo”`和`raise Exception.new(“foo”)`有什么区别?

时间:2011-01-26 01:40:39

标签: ruby exception exception-handling

之间有什么区别 - 技术,哲学,概念或其他方面
raise "foo"

raise Exception.new("foo")

2 个答案:

答案 0 :(得分:115)

从技术上讲,第一个引发RuntimeError,消息设置为"foo",第二个引发异常,消息设置为"foo"

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

简而言之,您可能想要RuntimeError而不是Exception。没有参数的救援区将捕获RuntimeErrors,但不会捕获Exception。因此,如果您在代码中引发Exception,则此代码将无法捕获它:

begin
rescue
end

为了抓住Exception,你必须这样做:

begin
rescue Exception
end

这意味着,从某种意义上说,Exception是一个比“{1}}更糟糕”的错误,因为你必须做更多的工作才能从中恢复。

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

同样,如果您正在编写库代码,您可能需要Exception,而不是RuntimeError,因为如果它引发空白{{1}的错误,您的库的用户会感到惊讶阻止无法捕获,并且需要花一点时间来实现原因。

最后,我应该说Exceptionrescue类的子类,实际的规则是尽管你可以RuntimeError 任何类型对象,空白StandardError默认只捕获从raise继承的任何内容。其他一切都必须具体。

答案 1 :(得分:31)

From the offical documentation:

raise   
raise( string )
raise( exception [, string [, array ] ] )

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

raise "Failed to create socket"
raise ArgumentError, "No parameters", caller