Rails 关于 Don't rescue Exception 的疑问

night_7th · 2016年01月19日 · 最后由 adamshen 回复于 2016年01月20日 · 2823 次阅读

今天看到了Rails Best Practice中的这么一条建议,Don't rescue Exception

Don't rescue Exception, rescue StandardError Explicitly rescuing Exception will rescue even not normally recoverable errors such as SyntaxError, LoadError, and Interrupt.

然而我自己在 demo 项目中测试了一下:

def index
  a )= 2 # Syntax error here
  @books = Book.all
rescue Exception => e
  logger.info "#{e}"
end

运行项目时却正常报错了,并没有被 rescue:

SyntaxError (/app/controllers/books_controller.rb:7: syntax error, unexpected ')', expecting keyword_end
    a )= 2
       ^):

我的 rails 版本是 4.2.5,很好奇是否这条规则已经失效了。

建议先看看 SyntaxError、StandardError 和 Exception 的关系。

def index
  eval("a )= 2") # Syntax error here
  @books = Book.all
rescue Exception => e
  logger.info "#{e}"
end

可能这条规则针对的是这种用 evalSyntaxError 的情形吧

@night_7th 感觉这里不必拘泥于是否捕获了SyntaxError,而要看到本质:Exception囊括了很多本不该我们捕获的异常,比如InterruptNoMemoryError

Exception
  NoMemoryError
  ScriptError
    LoadError
    NotImplementedError
    SyntaxError
  SignalException
    Interrupt
      Timeout::Error    # < ruby 1.9.2
  StandardError         # caught by rescue (default if no type was specified)
    ArgumentError
    IOError
      EOFError
    IndexError
    LocalJumpError
    NameError
      NoMethodError
    RangeError
      FloatDomainError
    RegexpError
    RuntimeError
      Timeout::Error    # >= ruby 1.9.2
    SecurityError
    SocketError
    SystemCallError
    SystemStackError
    ThreadError
    TypeError
    ZeroDivisionError
  SystemExit
  fatal

这个我记得 stackoverflow 上也有同样的问题。

@dorentus eval确实被 rescue 捕获住了,神奇

@qinfanpeng :plus1: 我就是好奇,因为syntax error最容易复现,就尝试了下

@adamshen这个么?

#6 楼 @night_7th 对的,这个 vote 数量很高的,当初出于好奇把 vote 前几页的问题都看了一遍,最高的居然是怎么写一个 case 语句,原来老外也是不看语法书的哈哈。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号