You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

i18n-active_record添加call方法报stack level too deep错误如何修复

问题根因

触发stack level too deep (SystemStackError)是无限递归导致,核心问题有两个:

  • 重写的call方法内调用store_default_translations时,该方法内部会再次触发翻译查找逻辑,查找失败会再次进入当前call方法,循环往复直到栈溢出。
  • 手动将自定义Missing模块include到I18n::Backend::ActiveRecord的方式错误,破坏了i18n-active_record原有的异常处理链路。i18n-active_record本身会将Missing模块作为独立的异常处理器注册到I18n异常处理链,不需要手动混入后端类。
修复代码
module I18n
  module Backend
    class ActiveRecord
      module Missing
        # 保留原call方法逻辑别名,避免覆盖后丢失原有异常处理能力
        alias_method :original_call, :call if method_defined?(:call)

        def call(exception, locale, key, options)
          if exception.is_a?(I18n::MissingTranslation)
            # 递归保护:正在处理该缺失翻译时直接返回空字符串,切断循环
            return '' if options[:i18n_processing_missing]
            options[:i18n_processing_missing] = true

            begin
              store_default_translations(locale, key, options)
            ensure
              options.delete(:i18n_processing_missing)
            end

            # 可根据业务需求替换返回值,比如返回默认提示文本
            ''
          else
            # 非缺失翻译类异常,走gem原有逻辑处理
            original_call(exception, locale, key, options)
          end
        end
      end
    end
  end
end

删除原有代码中I18n::Backend::ActiveRecord.send(:include, I18n::Backend::ActiveRecord::Missing)这一行,不需要手动执行模块注入。

关键说明
  • 递归标记是解决栈溢出的核心:执行默认翻译存储逻辑前打上标记,存储过程中内部触发的二次翻译查找会识别到标记直接返回,不会重复进入缺失处理流程。
  • 用alias保留原方法的非缺失异常处理分支,避免破坏gem原生的异常抛出、透传逻辑。
  • 不要手动修改Missing模块的加载方式,i18n-active_record初始化时会自动完成异常处理器注册。

内容的提问来源于stack exchange,提问作者Alejandro Cortés

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 06:18:21