代码之家  ›  专栏  ›  技术社区  ›  user3374124

无法捕获ActiveRecord::RecordNotFound with rescue

  •  1
  • user3374124  · 技术社区  · 7 年前

    我是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块中抛出类型错误时,打印了错误的错误消息。

    3 回复  |  直到 7 年前
        1
  •  1
  •   user3374124    7 年前

    原来错误消息是错误的。

    问题是我在炫耀 event_id (整数)转换为字符串。 但是Rails以某种方式打印出RecordNotFound异常。

    通过更换 Rails.logger.debug "Event does not exist, id: " + event_id 具有 Rails.logger.debug "Event does not exist, id: " + event_id.to_s

    感谢@lacostenycoder让我注意到错误消息。

        2
  •  1
  •   lacostenycoder    7 年前

    如果你这样做,你就不会出错

    事件=事件。查找依据(id:event\u id)

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

    你粘贴的代码对我来说很好。如果在日志中看不到输出,请检查您的环境和日志级别设置信息、警告、调试等。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 内部插值,而不是右引号和追加。

        3
  •  0
  •   Mohammad Kanan    7 年前

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