Ruby机架中间件,用于过滤堆栈中引发的所有异常

时间:2013-02-09 16:53:10

标签: ruby exception-handling rack middleware

您好我刚才有一个关于如何使用ruby rack正确管理异常处理的问题。

我目前正在使用Sinatra / Rack构建一个轻量级API,并且每个路由都可以通过异常(例如,缺少参数,无效格式等)。我希望能够捕获所有这些异常并在中间件应用程序中处理它们。我不想在每个获取,发布,放置,删除块中捕获或“拯救”(例如发布'/ me')

我试过这样的事情,其中​​ExceptionHandler位于机架堆栈的顶部。

我错过了什么?

class Api::ExceptionHandler

  def initialize(application)
    @application = application
  end

  def call(environment)
    @application.call environment
  rescue Api::MissingParameterError => parameter
    [ 400, { }, [ "parameter #{parameter} missing" ] ]
  end

end

2 个答案:

答案 0 :(得分:1)

自Sinatra 1.4版本(自版本0.11起由Padrino使用)以来,错误http状态定义发生了变化。以下是sinatra-1.4.2/lib/sinatra/base.rb与“handle_exception!”相关的部分。功能


 if boom.respond_to? :http_status    status(boom.http_status)  elsif settings.use_code? and boom.respond_to? :code and boom.code.between? 400, 599      status(boom.code)  else    status(500)  end

因此,如果您的异常类具有“http_status”方法,则从中定义错误状态。只有服务器错误(代码自500到599的错误)才能到达中间件,具体取决于“raise_errors”和“show_exceptions”设置(下面是相同的“handle_exception!”函数):

{{2} } 好消息,默认错误状态为500.因此,如果您确实需要例外传播中间件,只需防止您的异常类响应“http_status”方法或使用http_status代码从500到599.但是对于问题中最好的方法是使用像Max描述的   return res if res or not server_error?   raise boom if settings.raise_errors? or settings.show_exceptions? 方法。

答案 1 :(得分:0)

好吧,正如Catnapper所说,上面的代码应该有效!我没有提到的是我所有的中间件都继承了一个继承Sinatra :: Base的类。

Sinatra有自己的异常处理程序,可以像这样修改

set :raise_errors, false
set :show_exceptions, false

这就是你在sinatra中编写异常处理程序的方法(对于问题中的例子):

error Api::MissingParameterError do |parameter|
  status 400
  headers { }
  body "parameter #{parameter} missing"
end