您好我刚才有一个关于如何使用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
答案 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