"stack level too deep" Rails 5 在 "define_generate_prefix"
"stack level too deep" Rails 5 in "define_generate_prefix"
随机崩溃(Rails不会再运行),日志如下:
I, [2020-09-14T21:50:30.398707 #9732] INFO -- : [e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512] Completed 500 Internal Server Error in 10ms (ActiveRecord: 0.8ms)
F, [2020-09-14T21:50:30.406874 #9732] FATAL -- : [e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512]
F, [2020-09-14T21:50:30.406988 #9732] FATAL -- : [e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512] SystemStackError (stack level too deep):
F, [2020-09-14T21:50:30.407014 #9732] FATAL -- : [e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512]
F, [2020-09-14T21:50:30.407158 #9732] FATAL -- : [e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512] actionpack (5.2.4.4) lib/action_dispatch/routing/mapper.rb:689:in `block (2 levels) in define_generate_prefix'
[e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512] actionpack (5.2.4.4) lib/action_dispatch/routing/mapper.rb:689:in `block (2 levels) in define_generate_prefix'
<REPEATED AROUND 500 TIMES>
[e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512] actionpack (5.2.4.4) lib/action_dispatch/routing/mapper.rb:689:in `block (2 levels) in define_generate_prefix'
这仅在升级到 Rails 5 后才开始发生,并且在主内存较少的系统上更常发生。很难调试,因为它非常随机,通常仅在应用 运行 运行大约 24 小时后才会发生。
已尝试各种 ruby 版本,目前使用 ruby 2.5.5p157 with nginx 1.17.3 和 Phusion Passenger 6.0.4。
有人见过类似的东西吗?如果我可以随意复制它,我可能会调试自己,但随机性使它变得棘手。关于如何解决这样的问题有什么想法吗?
更新:
这似乎与这个问题非常相似(似乎还没有回答):Stack level too deep (SystemStackError) actionpack
更新 2
我现在看到任何已安装的引擎都会导致对 define_generate_prefix 的调用,例如带有已安装引擎的典型 config/routes.rb:
Rails.application.routes.draw do
devise_for :admins
resources :admins
mount MyEngine::Engine, :at => "/", :as => "my_engine"
end
在 mount 方法中将调用 define_generate_prefix
,后者又使用新的 find_script_name
方法扩展 app.routes
。请参阅此处的代码:https://github.com/rails/rails/blob/404ad9e8acf8ab45ae2314050131a00e57e63b40/actionpack/lib/action_dispatch/routing/mapper.rb#L687
最终效果是一个 super
方法在每个 mount
调用中一遍又一遍地叠加到前一个方法上。最终,当 url_for
调用 find_script_name
时,系统会发生堆栈溢出。这似乎是不可避免的
但是,我不是第一个看到这个的,所以我确定我的理解有问题。但是什么?
问题的 TL;DR 答案原来是:
不要在已安装的引擎中调用 Rails.application.reload_routes!
。
较长的解释是,当您安装了 Rails 引擎时调用 reload_routes!
会导致 mount
方法在 actionpack/lib/action_dispatch/routing/mapper.rb
中被调用,最终导致 app.routes
被一遍又一遍地扩展 (find_script_name
),每次你调用 reload_routes!
。在某些时候,您很可能会使用 url_for
助手,而这又会在您的 find_script_name
方法层中调用 super
,您将获得 stack too deep
错误。
这可能是 Rails 5 的错误并且似乎在 Rails 6 中重复出现,所以我看看是否应该在 Github.[=21 上提出问题=]
随机崩溃(Rails不会再运行),日志如下:
I, [2020-09-14T21:50:30.398707 #9732] INFO -- : [e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512] Completed 500 Internal Server Error in 10ms (ActiveRecord: 0.8ms)
F, [2020-09-14T21:50:30.406874 #9732] FATAL -- : [e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512]
F, [2020-09-14T21:50:30.406988 #9732] FATAL -- : [e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512] SystemStackError (stack level too deep):
F, [2020-09-14T21:50:30.407014 #9732] FATAL -- : [e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512]
F, [2020-09-14T21:50:30.407158 #9732] FATAL -- : [e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512] actionpack (5.2.4.4) lib/action_dispatch/routing/mapper.rb:689:in `block (2 levels) in define_generate_prefix'
[e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512] actionpack (5.2.4.4) lib/action_dispatch/routing/mapper.rb:689:in `block (2 levels) in define_generate_prefix'
<REPEATED AROUND 500 TIMES>
[e8eb6ebb-46eb-4d0e-93e2-e5d4fe6a8512] actionpack (5.2.4.4) lib/action_dispatch/routing/mapper.rb:689:in `block (2 levels) in define_generate_prefix'
这仅在升级到 Rails 5 后才开始发生,并且在主内存较少的系统上更常发生。很难调试,因为它非常随机,通常仅在应用 运行 运行大约 24 小时后才会发生。
已尝试各种 ruby 版本,目前使用 ruby 2.5.5p157 with nginx 1.17.3 和 Phusion Passenger 6.0.4。
有人见过类似的东西吗?如果我可以随意复制它,我可能会调试自己,但随机性使它变得棘手。关于如何解决这样的问题有什么想法吗?
更新: 这似乎与这个问题非常相似(似乎还没有回答):Stack level too deep (SystemStackError) actionpack
更新 2 我现在看到任何已安装的引擎都会导致对 define_generate_prefix 的调用,例如带有已安装引擎的典型 config/routes.rb:
Rails.application.routes.draw do
devise_for :admins
resources :admins
mount MyEngine::Engine, :at => "/", :as => "my_engine"
end
在 mount 方法中将调用 define_generate_prefix
,后者又使用新的 find_script_name
方法扩展 app.routes
。请参阅此处的代码:https://github.com/rails/rails/blob/404ad9e8acf8ab45ae2314050131a00e57e63b40/actionpack/lib/action_dispatch/routing/mapper.rb#L687
最终效果是一个 super
方法在每个 mount
调用中一遍又一遍地叠加到前一个方法上。最终,当 url_for
调用 find_script_name
时,系统会发生堆栈溢出。这似乎是不可避免的
但是,我不是第一个看到这个的,所以我确定我的理解有问题。但是什么?
问题的 TL;DR 答案原来是:
不要在已安装的引擎中调用 Rails.application.reload_routes!
。
较长的解释是,当您安装了 Rails 引擎时调用 reload_routes!
会导致 mount
方法在 actionpack/lib/action_dispatch/routing/mapper.rb
中被调用,最终导致 app.routes
被一遍又一遍地扩展 (find_script_name
),每次你调用 reload_routes!
。在某些时候,您很可能会使用 url_for
助手,而这又会在您的 find_script_name
方法层中调用 super
,您将获得 stack too deep
错误。
这可能是 Rails 5 的错误并且似乎在 Rails 6 中重复出现,所以我看看是否应该在 Github.[=21 上提出问题=]