你自己说的
将救援包裹在救援中
异常启动
除了将代码块包装在 begin rescue end 块中之外,没有其他特殊方法:
begin
do_something
rescue
begin
Logger.write ...
rescue
...error handling...
end
end
...除非您使用 ActiveSupport:http://api.rubyonrails.org/classes/Kernel.html#method-i-suppress
suppress(Exception) do
# all exceptions will be suppressed
end
..但这不是一个普通的 Ruby,我注意到你没有在你的问题中添加 rails 标签。不过,您可以自己实现suppress。或者,就拿这个吧:
def suppress(*exception_classes)
yield
rescue *exception_classes
end
在你的救援中使用它:
begin
do_something
rescue
Logger.write ...
suppress Exception do
...error handling...
end
end
在普通的旧 Ruby 中,它必须一直是救援(实际上,suppress 只是一个嵌套救援),但我只想说救援所有异常是一个坏主意,本质上,不被明确说明您要抢救的异常,换句话说,通过不将异常类参数传递给rescue,您隐式抢救了StandardError,这是大多数异常的超类(more info here)。这可能会导致难以发现错误。
begin
rescue
end
..等同于:
begin
rescue StandardError
end
最好知道你正在拯救什么异常并明确说明:
begin
rescue SomeApiError => e
# do something when this specific exception occurs
end
了解这一点后,您可以使用级联策略来挽救您的异常:
begin
# do the thing
rescue SomeApiError => e
# specific rescue
rescue SomeOtherError => e
# more broad error handling
rescue
# catch all rescue
end
在上述情况下,只有匹配引发异常的救援子句才会运行,但是救援块中的代码不会被后续救援所救援,只有 begin 块中的代码是可救援的。
如果您希望代码块即使在发生异常时也始终运行,请使用 ensure 关键字:
begin
# code
rescue => e
# rescue code
ensure
# this block will always run exception or not
end