我的用例是我想在sinatra中进行错误处理。为此,我正在设置错误处理程序如下
error 0..600 do
@@logger.error("error reason #{env['sinatra.error']}")
end
如果错误是由显式引发异常引起的,则sinatra.error变量设置为正确
get '/' do
raise "Fail the request"
end
但是,如果使用halt来终止请求,则不会设置sinatra.error。查看sinatra代码,这似乎与预期的一样,因为抛出:stop会导致控制流一直向上调用,从而绕过sinatra.error变量的设置。
我的问题是如何在暂停的同时使用错误处理程序,以便在错误处理程序中了解错误的原因。
我认为您看到的行为源于halt
的预期目的。当你调用它时,你不一定是在错误地发出信号;您只希望执行立即停止,这在过滤器中特别有用。如果你查看Sinatra的自述,它会说你使用halt
"立即停止过滤器或路由使用中的请求"。当然,你通常会因为一个错误而这么做。
值得注意的是,您定义的错误处理程序不仅在发生错误时被调用,而且在提供常规请求时也被调用,包括状态为200的请求。在这些情况下,也不会设置env[sinatra.error]
。
您可以在错误处理程序中检查异常,如果不可用,则检查响应代码。例如(注意这是一个经典的应用程序):
error 0..600 do
boom = @env['sinatra.error']
status = response.status
case
when boom != nil
puts 'exception: ' + boom
when status != 200
puts 'error: ' + status
end
end
一个结果是,在这个处理程序中,正常请求与被halt
中断的请求无法区分,因为两者都会生成200状态代码。但是,如果使用halt
报告错误,那么无论如何都应该使用类似500的错误代码。