我是 Ruby 新手,如果这是一个愚蠢的问题,或者我没有遵循最佳实践,请耐心等待。
我正在使用 find()
在数据库中查找一个对象,并期望它在 id 的对象不存在的情况下抛出 RecordNotFound
,如下所示.
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
但不知何故它没有被捕获(救援 block 中的日志没有打印)并且整个程序只是返回内部服务器错误。这是堆栈跟踪:
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,并且我捕获了错误的一个,但我不知道是否是这种情况或如何验证它。 我做错了什么?
========================================
更新
问题出在救援 block 中,我将 event_id
(整数)连接到字符串。
RecordNotFound
异常确实被捕获,但是当rescue block 中抛出类型错误时,打印了错误的错误消息。
最佳答案
如果这样做,您将不会收到错误
event = Event.find_by(id: event_id)
在这种情况下,如果无法通过 ID 找到记录,则 event == nil
将为 nil。
在这种情况下,如果无法通过 ID 找到记录,则 event == nil
将为 nil。
您粘贴的代码对我来说效果很好。如果您在日志中没有看到输出,请检查您的环境和日志级别设置 INFO、WARN、DEBUG 等。500 错误表示某种 Controller 操作引发了错误。
参见Set logging levels in Ruby on Rails
为了确保您的救援 block 正在执行,请尝试执行除日志之外的其他操作。如果您正在运行开发服务器,您可以尝试:
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
,而不是关闭引号和附加。
关于ruby-on-rails - 无法通过救援捕获 ActiveRecord::RecordNotFound,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49350120/