Rails局部视图随机变量赋值报错:No most-recent exception
我在做Bootstrap嵌套标签页的局部视图渲染,局部视图里还嵌套标签页,可能循环渲染相同局部视图形成无限嵌套结构。之前靠每次渲染时生成随机数作为div ID的一部分解决了ID重复导致标签页失效的问题,代码示例如下:
<% asdf = rand(1000000000) %> <div class="<% order.id %>_<%= @menu.order_type %>_<%= asdf %>"> <ul class="nav nav-tabs"> <li class="active"><a data-toggle="tab" href="#<%= order.id %>_<%= @menu.order_type %>_qwer_general_info_<%= asdf %>"><%= order.qwer_zxcv_name.upcase %>General</a></li> <!-- 其他标签页内容 --> </div>
但今早给变量wtf(示例里用asdf代替)赋值随机数时,突然报错:Error: No most-recent exception,其他变量赋值随机数都正常,昨天还能正常运行,想知道原因。
变量名冲突
wtf这个变量名大概率和框架(比如Rails/ERB的内置变量、方法)或你引入的第三方库重名了。昨天正常可能是因为没有触发冲突的场景,今天可能更新了依赖、修改了其他代码,导致赋值时触发了隐藏异常,而“没有最近的异常”这个提示是因为异常被上层逻辑吞掉,只留下模糊报错。
解决:换个语义明确且独特的变量名,比如tab_unique_suffix、random_tab_id,别用这种随意的缩写。ERB上下文异常
局部视图的渲染上下文可能被修改,导致rand的调用环境异常。虽然其他变量能赋值,但特定变量名可能触发了上下文里的钩子或代理逻辑,引发了未被正确抛出的异常。
解决:把随机数生成逻辑封装成辅助方法,比如在application_helper.rb里写:
def random_tab_suffix rand(1000000000) end
然后在模板里直接调用<%= random_tab_suffix %>,避开模板内赋值变量的上下文问题。
缓存/编译问题
模板缓存没清理,昨天的旧缓存还在,今天修改代码后缓存未更新,导致出现奇怪的报错。
解决:清空框架的临时缓存(比如Rails里执行rails tmp:clear),重启服务器再测试。换一种唯一ID生成方式
rand生成的数字存在重复概率,而且可能在特定场景下触发隐式异常。可以改用SecureRandom.uuid生成更唯一的ID,示例代码:
<% unique_id = SecureRandom.uuid %> <div class="<% order.id %>_<%= @menu.order_type %>_<%= unique_id %>"> <ul class="nav nav-tabs"> <li class="active"><a data-toggle="tab" href="#<%= order.id %>_<%= @menu.order_type %>_qwer_general_info_<%= unique_id %>"><%= order.qwer_zxcv_name.upcase %>General</a></li> <!-- 其他标签页内容 --> </div>
注意使用前需要确保require 'securerandom'(Rails项目一般默认已引入)。
内容的提问来源于stack exchange,提问作者daveasdf_2

