在sinatra中调用停止不会设置sinatra.error

时间:2012-01-19 11:07:08

标签: sinatra

我的用例是我想在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代码,这看起来像预期的那样因为throw:halt导致控制流一直向上调用,从而绕过sinatra.error变量的设置。

我的问题是如何使用错误处理程序以及暂停,以便我可以在错误处理程序中获取错误的原因。

1 个答案:

答案 0 :(得分:2)

我认为您所看到的行为源于halt的预期目的。当你打电话时,你不一定是错误的信号;你只想让执行立即停止,这在过滤器中特别有用。如果您查看Sinatra的自述文件,它会说您使用halt来"立即停止过滤器或路由使用中的请求"。当然,你通常会因为错误而这样做。

有趣的是注意到,您定义的错误处理程序不仅会在发生错误时调用,而且还会在提供常规请求时调用,包括状态为200的错误处理程序。在这些情况下,env[sinatra.error]赢了&#39 ;或者设置。

您可以在错误处理程序中执行的操作是检查异常,如果它不可用,请检查响应代码。例如(请注意,这是一个经典的应用程序):

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的错误代码。