我有一个3.0.7应用程序,使用github vhochstein/master的活动支架。我使用的是3.x兼容版本,它可以用作供应商/插件,而不需要安装gem。
在生产中,它命中ActionView::Template::Error(堆栈级别太深):。
beaumont@edouard:~/beaumont/current$ script/rails server -p 4000
ActionView::Template::Error (stack level too deep):
8: depth = Kernel.caller.count
9: logger.info "pagination: #{@page} #{depth}"
10: %>
11: <%= render :partial => 'list_pagination_links', :locals => { :current_page => @page } if @page.pager.infinite? || @page.pager.number_of_pages > 1 %>
12: </div>
13: <br clear="both" /><%# a hack for the Rico Corner problem %>
14: </div>
我开始在代码中寻找一些递归,然后在数据模型中寻找导致AS出错的循环。这首先发生在mod_passenger中,但也发生在脚本/轨道服务器登录服务器时。(这是我的测试版机器)
它总是在Rendered vendor/plugins/active_scafold/frontends/default/views/_list_pagination.html.erb(144.3ms157)中消亡。我入侵ActionView来记录Kernel.caller.count,这样我就可以看到堆栈是否在不断增长,但我看不到这一点。我确实看到堆叠深度高达180。在启动rails之前,我是否将堆栈限制得更大似乎并不重要,但可能有什么东西再次将堆栈限制回来。
在_list_pagination.html.erb中,它调用list_pagination_links。如果我评论掉这些电话,那么事情就不会失败。我试着让list_pagination_links什么都不做(没有代码!),但它在那个渲染调用中仍然失效。我想知道是在渲染代码本身中,堆栈是递归的,还是太大了。
这在我的笔记本电脑(debian sequeeze,32位)开发模式下不会发生,但在我的测试版机器(XEN VM,32位,debian crush)上确实会发生。它有时确实发生在我的笔记本电脑上,但不是以可重复的方式发生的,重新启动rails"解决"了问题。我还没有在我的笔记本电脑上尝试生产模式,我还怀疑它可能依赖于数据!
在处理完全相同的问题时,我发现了一种非常有用的调试方法,那就是Kernel的set_trace_func方法。
它基本上设置了一个在每个解释器"操作"之后调用的方法。如果你用它来打印一些信息,那么它可能会变得非常冗长,你的程序会变得非常慢,但你可以准确地看到发生了什么。如果它真的是一个无限递归,那么你会在一秒钟内看到错误行为的函数的名称充满你的屏幕。
在您的案例中使用的一个例子是:
<% set_trace_func proc { |event, file, line, id, binding, classname|
printf "%8s %s:%-2d %10s %8sn", event, file, line, id, classname
} %>
<%= render :partial => 'list_pagination_links', :locals => { :current_page => @page } if @page.pager.infinite? || @page.pager.number_of_pages > 1 %>
<% set_trace_func nil # disables tracing%>
到set_trace_func文档的链接
ps:我知道这不是一个真正意义上的答案,但它太长了,无法作为评论发布
当我在Active Scaffold中调试无限分页问题时,我添加了:
require 'active_scaffold/extensions/paginator_extensions'
到我的代码。这句话似乎是原因。我不知道为什么。
git平分线和逐行删除的代码发现了这一点。