我有一个带有rescue_from块的轨道控制器,我可以在其中调用render.
class SomeController < ApplicationController
rescue_from Some::Error, :some_error
private
def some_error error
@error = error
render 'error'
end
end
Run Code Online (Sandbox Code Playgroud)
奇怪的是,即使我有一个error.js.erb视图,rails也会一直使用error.html.erb,即使请求是JS:
Started GET /some/1
Processing by SomeController#show as JS
...
Rendered some/error.html.erb
Run Code Online (Sandbox Code Playgroud)
不是如何在它上面的缩短日志中表示它呈现为JS,但它仍然使用HTML文件.该.js.erb是在正确的位置,并呈现JS的看法时,有没有rescue_from涉及的作品就好了.
这里发生了什么?
更新1:我已经创建了一个测试存储库来演示该问题
更新2 我找到了解决方案(见下文).任何人都可以提出一个更通用的解决方案,如下面的那些,或者你能告诉我为什么这将是不可能的或一个非常糟糕的主意?赏金仍然开放.
self.formats在ActionController::Rescue.process_action 或解
我在rails源代码中做了一些调试和挖掘,并自己找到了一个解决方案:
def error
@error = error
self.formats = request.formats.map(&:ref).compact
render 'error'
end
Run Code Online (Sandbox Code Playgroud)
说明
调用rescue_from块发生在ActionController::Rescue.process_action.如果有错误,将调用该块.如果没有错误,最终ActionController::Rendering.process_action会调用刚刚设置的self.formats:
def process_action(*) #:nodoc:
self.formats = request.formats.map(&:ref).compact
super
end
Run Code Online (Sandbox Code Playgroud)
这是一个完整的堆栈跟踪ActionController::Rescue.process_action和实际的控制器操作.
#0 TestController.index at /tmp/rescue_from/app/controllers/test_controller.rb:11
#1 ActionController::ImplicitRender.send_action(method#String, *args#Array) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.3/lib/action_controller/metal/implicit_render.rb:4
#2 AbstractController::Base.process_action(action#NilClass, *args#Array) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.3/lib/abstract_controller/base.rb:198
#3 ActionController::Rendering.process_action(action, *args) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.3/lib/action_controller/metal/rendering.rb:10
#4 block in AbstractController::Callbacks.process_action(action#NilClass, *args#Array) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.3/lib/abstract_controller/callbacks.rb:20
?-- #5 Proc.call(*args) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:115
#6 ActiveSupport::Callbacks::Filters::End.call(env#ActiveSupport::Callbacks::Filters::Environment) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:115
#7 block (2 levels) in ActiveSupport::Callbacks::CallbackChain.compile at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:553
?-- #8 Proc.call(*args) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:503
#9 ActiveSupport::Callbacks::CallbackSequence.call(*args#Array) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:503
#10 ActiveSupport::Callbacks.run_callbacks(kind#Symbol, &block#Proc) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activesupport-4.2.3/lib/active_support/callbacks.rb:88
#11 AbstractController::Callbacks.process_action(action#NilClass, *args#Array) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.3/lib/abstract_controller/callbacks.rb:19
#12 ActionController::Rescue.process_action(action#NilClass, *args#Array) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.3/lib/action_controller/metal/rescue.rb:29
Run Code Online (Sandbox Code Playgroud)
当出现错误时(抛出a before_action),这是一个完整的堆栈跟踪:
--> #0 TestController.standard_error(error#RuntimeError) at /Users/timou/tmp/rescue_from/app/controllers/test_controller.rb:20
?-- #1 Method.call(*args) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activesupport-4.2.3/lib/active_support/rescuable.rb:80
#2 ActiveSupport::Rescuable.rescue_with_handler(exception#RuntimeError) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activesupport-4.2.3/lib/active_support/rescuable.rb:80
#3 ActionController::Rescue.rescue_with_handler(exception#RuntimeError) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.3/lib/action_controller/metal/rescue.rb:15
#4 rescue in ActionController::Rescue.process_action(action#NilClass, *args#Array) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.3/lib/action_controller/metal/rescue.rb:32
#5 ActionController::Rescue.process_action(action#NilClass, *args#Array) at /usr/local/Cellar/rbenv/0.4.0/versions/2.2.2/lib/ruby/gems/2.2.0/gems/actionpack-4.2.3/lib/action_controller/metal/rescue.rb:29
Run Code Online (Sandbox Code Playgroud)
所以我的问题实际上是错误是在a中引发的before_action,这是由设置AbstractController::Callbacks.process_action之前处理和发生的.ActionController::Rendering.process_actionself.formats
如果错误的行动本身提出,self.formats将已经被设置和正确政绩观将不设置被渲染self.formats的rescue_from块.
| 归档时间: |
|
| 查看次数: |
397 次 |
| 最近记录: |