【问题标题】:Why can't I catch the test exception in the "caller" method?为什么我不能在“调用者”方法中捕获测试异常?
【发布时间】:2012-01-31 03:54:27
【问题描述】:

我不明白为什么这段代码不能正常工作:

def test
  raise Exception.new 'error'
end

def caller
  begin
    test
  rescue =>e
     puts e.message
  end
end

caller

我想在caller方法中捕获测试异常,但是caller方法似乎没有捕获任何东西。

【问题讨论】:

  • fwiw,在方法中执行begin rescue end 时,可以删除beginend。节省几行代码,即def caller;test;rescue Exception=>e;puts e.message;end
  • 作为一个风格的东西,你不需要在引发异常时使用newraise Exception, 'error' 就足够了。

标签: ruby exception


【解决方案1】:

您的代码不起作用的原因是因为rescue 没有明确声明的异常类型只能捕获StandardError,它是Exception 的子类。由于您提高了Exception,它高于StandardError,因此您的rescue 无法捕捉到它。

通常您希望使用更具体的异常,并且您几乎不需要使用Exception 而不是StandardError

例如,这可以正常工作:

begin
  raise StandardError.new 'Uh-oh!'
rescue => e
  p e.message
end

#=> Uh-oh!

【讨论】:

  • “通常你想使用更具体的例外”,同意。增加的粒度有助于在“战斗条件”中处理流控制。
【解决方案2】:

您应该指定您希望rescue 的异常类型。试试

  rescue Exception => e

【讨论】:

  • 谢谢,效果很好。我无法理解 throw 和 raise 语句之间的区别...
  • 不一定……看我的回答。 rescue Exception => e 通常是个坏主意,因为您可能正在捕获比您的应用程序准备处理的更低级别的异常。
  • @BenD,抛出/提高差异were covered in this question
  • 我同意 coreyward 的观点:更好的建议是首先不要提出 Exception,而是使用更具体的错误类,例如 StandardError
【解决方案3】:

Jan 打败了我,但是...

当您将=> var 语法与exception 一起使用时,您必须指定要挽救的异常类型。所有异常的基类都是 Exception,因此如果将其更改为 rescue Exception => e,它将起作用。此外,当您要拯救的是整个方法体时,您不需要显式的 begin...end 块...

def test
  raise Exception.new 'error'
end

def caller
  test
rescue Exception =>e
  puts e.message
end

caller()

【讨论】:

  • 再一次,这不一定是真的。您可能不想想要rescue Exception => e,因为您将捕获比您的程序能够处理的更低级别的异常。
  • 当然,我应该提到拯救Exception通常不是一件好事。因为,在这种情况下,Exception 是被提出的,但是,...
猜你喜欢
  • 2021-03-16
  • 2010-12-07
  • 2014-11-24
  • 1970-01-01
  • 2020-07-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多