begin
do_something
rescue
Logger.write ...
...error handling...
end
问题是,救援 中的代码 可能会引发异常。对于这个用例,我想压制它。
那么,如何将救援包裹起来以抑制异常呢?
答案 0 :(得分:3)
你自己说了
救援救援
例外初始
除了在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
这是大多数异常的超类({{3} })。这可能导致很难找到错误。
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
如上所述,只有与引发的异常匹配的rescue子句会运行,但是救援块中的代码不会被后续的救援拯救,只有begin
块中的代码才能被抢救。
如果您想拥有一个即使在发生异常时也始终运行的代码块,请使用ensure
关键字:
begin
# code
rescue => e
# rescue code
ensure
# this block will always run exception or not
end