#2103·sinatra

尽管设置了 `set :show_exceptions, :after_handler`, catch-all 错误处理器在 dev 中却从未运行

作者: davetron5000创建于 2025年5月4日更新于 2025年5月4日

文档中这样写着:

错误处理器在路由块或过滤器中引发异常时被调用。但是,请注意,在开发阶段,只有在将 show_exceptions 选项设置为 :after_handler 时才会运行: set :show_exceptions, :after_handler 可以使用 error 和一个块定义一个捕获所有错误的处理器: error do '很抱歉,发生了一个严重的错误' end 这让我怀疑在开发阶段,error do(捕获所有错误)将被调用。然而,事实并非如此。 值得注意的是,如果底层错误是请求错误或未找到,捕获所有错误也不会被调用。 这是由于以下代码: https://GitHub.com/sinatra/sinatra/blob/91cfb548c9e50a65324a9ce9e4ea5f10cd897027/lib/sinatra/base.rb#L1235-L1252 如果没有配置的处理器匹配,我们将继续到第 1239 行,检查未找到和请求错误。如果其中任何一个为真,将发生硬编码行为,捕获所有错误不会被调用。 如果不是请求错误或未找到,执行将继续到第 1250 行。由于 :show_exceptions 设置为 :after_handler,该值为真,捕获的异常将被重新抛出,捕获所有错误不会被调用。 另外值得注意的是,您无法通过 error Exception do 避免此行为。error StandardError do 对于继承 StandardError 的任何内容都有效,但这并不是真正的捕获所有错误。

建议的解决方案

  • 最简单的方法是文档说明捕获所有错误并不捕获所有错误,并且要真正捕获所有错误,您必须使用 error Exception do
  • 另一种选择是重写此代码,使捕获所有错误的处理器真正捕获所有错误,但这可能被视为一个突变更改,如果有人依赖当前行为。

内容来源: sinatra/sinatra