Skip to content

Commit b2e4192

Browse files
committed
Explicitly call I18n.exception_handler on missing translation
Fix: rails#54419 Since `TranslationHelper#translate` always sets a `default`, missing translation is never considered like an error by `I18n` and the error handler is never called. This makes I18n's exception handler pretty much unusable. The solution is to explictly call it ourselves, but the downside is we need to allocate that exception, which isn't free, but supposedly it's not expected to happen often.
1 parent 728a2d5 commit b2e4192

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

actionview/lib/action_view/helpers/translation_helper.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,12 @@ def scope_key_by_partial(key)
140140
end
141141

142142
def missing_translation(key, options)
143-
keys = I18n.normalize_keys(options[:locale] || I18n.locale, key, options[:scope])
143+
locale = options[:locale] || I18n.locale
144+
145+
i18n_exception = I18n::MissingTranslation.new(locale, key, options)
146+
I18n.exception_handler.call(i18n_exception, locale, key, options)
147+
148+
keys = I18n.normalize_keys(locale, key, options[:scope])
144149

145150
title = +"translation missing: #{keys.join(".")}"
146151

actionview/test/template/translation_helper_test.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,28 @@ def test_default_lookup_scoped_by_partial
172172
assert_equal "Foo", view.render(template: "translations/templates/default").strip
173173
end
174174

175+
def test_missing_translation_reported_to_i18n_exception_handler
176+
previous_handler = I18n.exception_handler
177+
178+
calls = []
179+
I18n.exception_handler = ->(*args) { calls << args }
180+
view.render(template: "translations/templates/missing")
181+
182+
first_call = calls.first
183+
assert_not_nil first_call
184+
exception = first_call.first
185+
assert_instance_of I18n::MissingTranslation, exception
186+
assert_equal "translations.templates.missing.missing", exception.key
187+
188+
assert_equal 1, calls.size
189+
190+
assert_nothing_raised do
191+
previous_handler.call(*first_call)
192+
end
193+
ensure
194+
I18n.exception_handler = previous_handler
195+
end
196+
175197
def test_missing_translation_scoped_by_partial
176198
expected = '<span class="translation_missing" title="translation missing: en.translations.templates.missing.missing">Missing</span>'
177199
assert_equal expected, view.render(template: "translations/templates/missing").strip

0 commit comments

Comments
 (0)