开始救援没有发现错误
Posted
技术标签:
【中文标题】开始救援没有发现错误【英文标题】:Begin Rescue not catching error 【发布时间】:2011-03-11 05:40:24 【问题描述】:我正在使用一些包含在 begin - rescue 块中的 ruby 代码,但不知何故它仍然会崩溃。
代码块如下所示:
# Retrieve messages from server
def get_messages
@connection.select('INBOX')
@connection.uid_search(['ALL']).each do |uid|
msg = @connection.uid_fetch(uid,'RFC822').first.attr['RFC822']
begin
process_message(msg)
add_to_processed_folder(uid) if @processed_folder
rescue
handle_bogus_message(msg)
end
# Mark message as deleted
@connection.uid_store(uid, "+FLAGS", [:Seen, :Deleted])
end
end
鉴于此代码,我假设如果 process_message 或 add_to_processed_folder 无法执行,则救援将启动并调用 handle_bogus_message。话虽如此,我在生产环境中运行此代码,有时当我“收到”一封电子邮件(这是从 rake 任务运行的)时,它会因 SyntaxError 而死。
要查看错误消息,请查看http://pastie.org/1028479,而不是它所指的 process_message 与上面的 process_message 相同。 begin - rescue 不会捕获此异常有什么原因吗?
【问题讨论】:
【参考方案1】:rescue
不带参数只会挽救从StandardError
继承的异常。要拯救SyntaxError
,请使用rescue SyntaxError
。
如here 和here 解释的那样,为了挽救所有异常,您将使用rescue Exception
,但请注意这是一个坏主意(这就是为什么它不是rescue
的默认行为的原因)。尤其是这部分:
救援中断可防止用户使用 CTRLC 退出程序。
救援 SignalException 会阻止程序正确响应信号。除非 kill -9,否则它将无法杀死。
【讨论】:
rescue
默认不救援Exception
s 的原因是他们通常被认为过于严重而无法救援。【参考方案2】:
rescue
不带任何参数接受由 StandardError 类引发的异常。您的错误类型是 SyntaxError,它继承自另一个名为 ScriptError 的类。所有这些错误类都是异常类的子类。所以 sepp2k 建议使用rescue Exception
来捕获各种异常。
【讨论】:
以上是关于开始救援没有发现错误的主要内容,如果未能解决你的问题,请参考以下文章
以 DRY 方式将多个错误类传递给 ruby 的救援子句