【问题标题】:Can't catch ActiveRecord::RecordNotFound with rescue无法通过救援捕获 ActiveRecord::RecordNotFound
【发布时间】:2018-08-27 06:07:00
【问题描述】:

我是 Ruby 新手,如果这是一个愚蠢的问题,或者我没有遵循最佳实践,请多多包涵。

我正在使用find() 在数据库中找到一个对象,并希望它抛出RecordNotFound,以防 id 的对象不存在,像这样。

  begin
    event = Event.find(event_id)
  rescue ActiveRecord::RecordNotFound => e
    Rails.logger.debug "Event does not exist, id: " + event_id
    return {
        # return "unauthorized" to avoid testing existence of event id
        # (some redacted codes)
    }
  end 

但不知何故,它没有被捕获(救援块中的日志没有打印),整个程序只是返回内部服务器错误。这是堆栈跟踪:

Completed 500 Internal Server Error in 22ms (ActiveRecord: 1.0ms)



ActiveRecord::RecordNotFound (Couldn't find Event with 'id'=999):

lib/sync/create_update_event_handler.rb:78:in `handleRequest'
app/controllers/sync_controller.rb:36:in `block in sync'
app/controllers/sync_controller.rb:31:in `each'
app/controllers/sync_controller.rb:31:in `sync'
  Rendering /usr/local/rvm/gems/ruby-2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout
  Rendering /usr/local/rvm/gems/ruby-2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb
  Rendered /usr/local/rvm/gems/ruby-2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_source.html.erb (6.4ms)
  Rendering /usr/local/rvm/gems/ruby-2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb
  Rendered /usr/local/rvm/gems/ruby-2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.3ms)
  Rendering /usr/local/rvm/gems/ruby-2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
  Rendered /usr/local/rvm/gems/ruby-2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.9ms)
  Rendered /usr/local/rvm/gems/ruby-2.4.0/gems/actionpack-5.0.6/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (36.6ms)

我唯一能想到的是有两个不同的 ActiveRecord::RecordNotFound,我抓错了一个,但我不知道是否是这种情况或如何验证它。 我做错了什么?

========================================

更新

问题出在救援块中,我将event_id(一个整数)连接到一个字符串。 RecordNotFound 异常确实被捕获了,但是在rescue块中抛出类型错误时,打印了错误的错误信息。

【问题讨论】:

  • 我不确定您的问题,但这些链接可能会对您有所帮助。 stackoverflow.com/questions/12849597/… 以及阅读有关 Rails 的 rescue_from 功能的信息,该功能可让您在控制器本身上为特定异常定义模板。
  • 您确定在event = Event.find(event_id) 行上出现ActiveRecord::RecordNotFound 错误吗?
  • @MartinZinovsky 我很确定,因为浏览器上显示的堆栈跟踪突出显示了该行。对我来说太奇怪了,我明确地捕获了该异常,但它仍然导致内部服务器错误。
  • @user3374124 你能在你的问题中发布完整的操作代码吗?
  • 那条线上lib/sync/create_update_event_handler.rb:78 没有什么会引发该错误?那么服务器日志呢? Rails.logger.debug 应该打印,以防错误得到挽救。如果它的控制器操作,您也可以将 return 更改为 render

标签: ruby-on-rails ruby rails-activerecord


【解决方案1】:

这样做不会出错

event = Event.find_by(id: event_id)

在这种情况下,如果无法通过 ID 找到记录,则 event == nil 将为零。 在这种情况下,如果无法通过 ID 找到记录,则 event == nil 将为零。

您粘贴的代码对我来说很好用。如果您没有在日志中看到输出,请检查您的环境和日志级别设置 INFO、WARN、DEBUG 等。500 错误表示某种控制器操作引发了错误。

Set logging levels in Ruby on Rails

为确保您的救援块正在执行,请尝试执行日志之外的其他操作。如果您正在运行开发服务器,您可以尝试:

    begin
         event = Event.find(event_id)
     rescue ActiveRecord::RecordNotFound => e
         msg = "Event does not exist, id: #{event_id.to_s}"
         Rails.logger.debug msg.
         puts msg 
         binding.pry # if you have gem 'pry' in your development gems.
         File.open('test.log', 'w') {|f| f.write msg} #check if this appears in root of your app
         return {
                 # return "unauthorized" to avoid testing existence of event id
                 # (some redacted codes)
         }
     end 

更新:我根据您的回答更改了字符串插值。您也可以在插值内调用.to_s,而不是关闭引号和附加。

【讨论】:

  • 感谢您的想法。你的建议让我注意到了救援块的内容,在那里我发现了问题,仅供参考,我没有对你的回复投反对票。
  • 感谢您的想法。你的建议让我注意到了救援块的内容,我发现了问题所在。问题是错误消息,我将event_id(整数)连接到一个字符串。仅供参考,我没有否决您的回复。
【解决方案2】:

@event = Event.find(params[:id])。你应该改写params[:id] 。这是错误的原因。

【讨论】:

  • 谢谢,这就是我使用的解决方法。但我试图找出我的代码出了什么问题,而不是避免异常。
【解决方案3】:

原来错误信息是错误的。

问题是我将event_id(一个整数)集中到一个字符串中。 但不知何故,Rails 打印出 RecordNotFound 异常。

问题已通过替换解决 Rails.logger.debug "Event does not exist, id: " + event_idRails.logger.debug "Event does not exist, id: " + event_id.to_s

感谢@lacostenycoder 提醒我注意错误消息。

【讨论】:

  • 很高兴我能提供帮助。我更新了我的答案。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-30
  • 1970-01-01
  • 1970-01-01
  • 2018-06-05
  • 1970-01-01
  • 2012-05-08
  • 1970-01-01
相关资源
最近更新 更多