关于rails上的ruby:无法通过救援捕获ActiveRecord :: RecordNotFound

Can't catch ActiveRecord::RecordNotFound with rescue

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

我在使用find()在数据库中找到一个对象,并且如果id的对象不存在,则期望它抛出RecordNotFound,就像这样。

1
2
3
4
5
6
7
8
9
  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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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块中抛出类型错误时,打印出错误的错误消息。


原来错误信息是错误的。

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

通过替换解决了这个问题
<5233>

Rails.logger.debug"Event does not exist, id:" + event_id.to_s

感谢@lacostenycoder将我的注意力集中在错误消息上。


如果你这样做,你不会得到错误

event = Event.find_by(id:event_id)

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

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

请参阅在Ruby on Rails中设置日志记录级别

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

1
2
3
4
5
6
7
8
9
10
11
12
13
    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 = Event.find(params[:id])。你应该写params[:id]。这就是错误的原因。