2017-06-29 58 views
2

一些背景:我在一个大的代码库(Rails)中有一些Ruby代码,在特定条件下引发异常。然而,例外情况不像预期的那样“发生”,它被无声地丢弃。我认为其他一些代码(宝石)可能会意外地拯救这个异常。如何确定在Ruby中正在救援的异常?

如何确定哪里有异常正在救援?

我完全可以控制这个异常。所以也许有一种例外的方法可以知道什么时候被救出?

人为的例子:

# code outside my control 
def foo 
    yield 
rescue 
end 

def black_box(&block) 
    foo(&block) 
end 

# my code 
black_box do 
    puts 'about to raise' 
    raise 
    puts 'never gets here' 
end 

输出:

about to raise 

所以异常被救出。我如何识别(从“我的代码”中)它在foo中被救出?

+2

你可以假设外国的宝石有异常情况_something_,而不是默默地跳过它。尝试将断点放到'#message','#cause'等并检查意外中断。幸运的话,你会在堆栈顶部获得调用者。 – mudasobwa

+1

@mudasobwa确实,工作!在验收测试中,由于'config.action_dispatch.show_exceptions = false',Rails本身解救了这个异常。 – Stefan

+0

很酷。 Rails做了太多的魔术,这就是为什么我更喜欢COBOL :) – mudasobwa

回答

1

我能想到的唯一方法就是手动调试/检查。

当您打算提出您希望跟踪的异常时,请检查当前的caller。这给你一个调用堆栈。现在访问你的编辑器中的每一行/方法,并寻找过于贪婪的救援。

至于更“自动”的方式,我没有看到任何。 Ruby异常没有on_rescue回调或类似的东西,所以他们不知道他们正在被救出。

+0

115行的调用堆栈:-( – Stefan

+2

@Stefan:你很幸运,它是一个小的:) –

+0

无赖,'TracePoint'也没有帮助,它有一个':raise'事件,但没有':rescue'。 – Stefan