Ruby中的Sinatra错误处理

Tjrburgess

我有一个简单的Sinatra休息,并且无法捕获错误。我也承认我对Ruby和Sinatra相当陌生。

当我在post端点引发错误时,我想报告传入的文档。我需要1)处理发布结果中的错误(我可以访问@incoming)或2)将传入的文档传递给错误并在那里报告错误。

什么是更好的选择,选项1或选项2?

  • 如果我坚持使用选项1,如何防止错误发生(现在似乎正在这样做)
  • 如果我转到选项2,如何将输入传递给错误?

以下是我的代码示例:

post ('/result') do 

  begin  
  @incoming = JSON.parse(request.body.read)

  //do something that causes an error
  rescue
     e = env['sinatra.error']
     url = request.url
     ip = request.ip

     @actlogpassblock = {  :message => e.message,
                        :path => url,
                        :ip => ip,
                        :timestamp => Time.new,
                        :type => "500",
                        :sub => "RES",
                        :payload => @incoming
                      }        
    action_log.insert(@actlogpassblock)
    status 500 
  end
end

error do
   status 500 
   e = env['sinatra.error']
   url = request.url
   ip = request.ip
   backtrace = "Application error\n#{e}\n#{e.backtrace.join("\n")}"

  @actlogpassblock = {  :message => e.message,
                        :path => url,
                        :ip => ip,
                        :timestamp => Time.new,
                        :type => "500",
                        :backtrace => backtrace
                      }        
  action_log.insert(@actlogpassblock)
  {:result => 'Ah Shucks! Something went wrong'}.to_json
end
7stud

如果我坚持使用选项1,如何防止错误发生(现在似乎正在这样做)

根据文档:

每当从路由块引发异常时,都会调用错误处理程序。

但是,这仅适用于未捕获的异常。尝试这个:

require 'sinatra'
set :show_exceptions, false

get '/' do
  begin
    raise ZeroDivisionError
  rescue ZeroDivisionError
    "rescue clause"
  end
end

error do
  "sinatra error handler" 
end

然后试试这个:

get '/' do
  raise ZeroDivisionError
end

error do
  "sinatra error handler" 
end

另外,您可以定制错误处理程序以仅捕获某些异常,从而避免某些异常,例如

error IndexError do ...

或者

error MyCustomException do ...

或者

error 400..510 do

但是要抓住所有版本:

error do

当路由块中发生未捕获的异常时,您无法阻止其执行...除非:

仅当Sinatra :raise_errors:show_exceptions配置选项都设置为false时,才会调用错误处理程序

:raise_errors在“测试”环境中默认为true,在其他环境中默认为false。

:show_exceptions值在“开发”环境中默认为true,在其他环境中为false

Sintra的作者说:“这种(行为)是故意的。想法是错误块将隐藏问题,并且您通常不希望在开发模式下这样做。

https://github.com/sul-dlss/sdr-services-app/blob/master/Sinatra-error-handling.md

如果我转到选项2,如何将输入传递给错误?

在错误块内可以看到在路由块内创建的@variable。试试这个:

require 'sinatra'
set :show_exceptions, false

get '/' do
  @incoming = "hello world"    #create @variable
  raise ZeroDivisionError
end

error ZeroDivisionError do
  @incoming                    #retrieve @variable
end

http://localhost:4567浏览器中输入网址后,您应该在返回的网页上看到“ hello world”。

起作用的原因是因为@variable在创建@variable时将自身附加到任何对象本身。同样,在调用@variable时,它会从当时自己的任何对象中检索。当Sinatra执行路由块或错误块时,它将自身设置为同一对象。

选项2看起来不错,因为它可以将错误处理代码与应用程序代码分开。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章