Permalink
Browse files

Switch from I18n::MissingTranslationData (which is an Exception) to I…

…18n::MissingTranslation (which is a plain Object) for the default case. Create an I18n::MissingTranslationData exception only if it needs to be raised to the user.
  • Loading branch information...
1 parent fc6485f commit 9d85541a5ed34a2afca8e49715945ed0b94a2935 Sven Fuchs committed Feb 27, 2011
View
@@ -156,7 +156,7 @@ def translate(*args)
backend.translate(locale, key, options)
end
end
- result.is_a?(MissingTranslationData) ? handle_exception(handling, result, locale, key, options) : result
+ result.is_a?(MissingTranslation) ? handle_exception(handling, result, locale, key, options) : result
end
alias :t :translate
@@ -266,7 +266,7 @@ def normalize_keys(locale, key, scope, separator = nil)
# Any exceptions thrown in translate will be sent to the @@exception_handler
# which can be a Symbol, a Proc or any other Object unless they're forced to
- # be raised or thrown (MissingTranslationData).
+ # be raised or thrown (MissingTranslation).
#
# If exception_handler is a Symbol then it will simply be sent to I18n as
# a method call. A Proc will simply be called. In any other case the
@@ -285,7 +285,7 @@ def normalize_keys(locale, key, scope, separator = nil)
def handle_exception(handling, exception, locale, key, options)
case handling
when :raise
- raise exception
+ raise(exception.respond_to?(:to_exception) ? exception.to_exception : exception)
when :throw
throw :exception, exception
else
@@ -325,8 +325,7 @@ def normalize_translation_keys(locale, key, scope, separator = nil)
def default_exception_handler(exception, locale, key, options)
puts "I18n.default_exception_handler is deprecated. Please use the class I18n::ExceptionHandler instead " +
"(an instance of which is set to I18n.exception_handler by default)."
- return exception.message if MissingTranslationData === exception
- raise exception
+ exception.is_a?(MissingTranslation) ? exception.message : raise(exception)
end
end
end
@@ -34,7 +34,7 @@ def translate(locale, key, options = {})
default(locale, key, default, options) : resolve(locale, key, entry, options)
end
- throw(:exception, I18n::MissingTranslationData.new(locale, key, options)) if entry.nil?
+ throw(:exception, I18n::MissingTranslation.new(locale, key, options)) if entry.nil?
entry = entry.dup if entry.is_a?(String)
entry = pluralize(locale, entry, count) if count
@@ -119,7 +119,7 @@ def resolve(locale, object, subject, options = {})
subject
end
end
- result unless result.is_a?(MissingTranslationData)
+ result unless result.is_a?(MissingTranslation)
end
# Picks a translation from an array according to English pluralization
@@ -70,7 +70,7 @@ def translate(locale, key, options = {})
def fetch(cache_key, &block)
result = _fetch(cache_key, &block)
- throw(:exception, result) if result.is_a?(MissingTranslationData)
+ throw(:exception, result) if result.is_a?(MissingTranslation)
result = result.dup if result.frozen? rescue result
result
end
@@ -54,7 +54,7 @@ def translate(locale, key, default_options = {})
end
return namespace if namespace
- throw(:exception, I18n::MissingTranslationData.new(locale, key, options))
+ throw(:exception, I18n::MissingTranslation.new(locale, key, options))
end
def localize(locale, object, format = :default, options = {})
@@ -63,7 +63,7 @@ def localize(locale, object, format = :default, options = {})
result = backend.localize(locale, object, format, options) and return result
end
end
- throw(:exception, I18n::MissingTranslationData.new(locale, format, options))
+ throw(:exception, I18n::MissingTranslation.new(locale, format, options))
end
protected
@@ -29,8 +29,7 @@ module Fallbacks
# locale :"de-DE" it might try the locales :"de-DE", :de and :en
# (depends on the fallbacks implementation) until it finds a result with
# the given options. If it does not find any result for any of the
- # locales it will then raise a MissingTranslationData exception as
- # usual.
+ # locales it will then throw MissingTranslation as usual.
#
# The default option takes precedence over fallback locales
# only when it's a Symbol. When the default contains a String or a Proc
@@ -49,7 +48,7 @@ def translate(locale, key, options = {})
options.delete(:fallback)
return super(locale, nil, options.merge(:default => default)) if default
- throw(:exception, I18n::MissingTranslationData.new(locale, key, options))
+ throw(:exception, I18n::MissingTranslation.new(locale, key, options))
end
def extract_string_or_lambda_default!(options)
@@ -6,7 +6,7 @@ module I18n
class ExceptionHandler
include Module.new {
def call(exception, locale, key, options)
- if exception.is_a?(MissingTranslationData)
+ if exception.is_a?(MissingTranslation)
options[:rescue_format] == :html ? exception.html_message : exception.message
else
raise exception
@@ -33,25 +33,41 @@ def initialize(filename)
end
end
- class MissingTranslationData < ArgumentError
- attr_reader :locale, :key, :options
+ class MissingTranslation
+ module Base
+ attr_reader :locale, :key, :options
- def initialize(locale, key, opts = nil)
- @key, @locale, @options = key, locale, opts.dup || {}
- options.each { |k, v| options[k] = v.inspect if v.is_a?(Proc) }
- super "translation missing: #{keys.join('.')}"
- end
+ def initialize(locale, key, options = nil)
+ @key, @locale, @options = key, locale, options.dup || {}
+ options.each { |k, v| self.options[k] = v.inspect if v.is_a?(Proc) }
+ end
- def html_message
- key = keys.last.to_s.gsub('_', ' ').gsub(/\b('?[a-z])/) { $1.capitalize }
- %(<span class="translation_missing" title="translation missing: #{keys.join('.')}">#{key}</span>)
- end
+ def html_message
+ key = keys.last.to_s.gsub('_', ' ').gsub(/\b('?[a-z])/) { $1.capitalize }
+ %(<span class="translation_missing" title="translation missing: #{keys.join('.')}">#{key}</span>)
+ end
+
+ def keys
+ @keys ||= I18n.normalize_keys(locale, key, options[:scope]).tap do |keys|
+ keys << 'no key' if keys.size < 2
+ end
+ end
+
+ def message
+ "translation missing: #{keys.join('.')}"
+ end
+ alias :to_s :message
- def keys
- @keys ||= I18n.normalize_keys(locale, key, options[:scope]).tap do |keys|
- keys << 'no key' if keys.size < 2
+ def to_exception
+ MissingTranslationData.new(locale, key, options)
end
end
+
+ include Base
+ end
+
+ class MissingTranslationData < ArgumentError
+ include MissingTranslation::Base
end
class InvalidPluralizationData < ArgumentError
@@ -9,7 +9,7 @@ class ExceptionHandler
# are forced to html_safe
include Module.new {
def call(exception, locale, key, options)
- exception.is_a?(MissingTranslationData) ? super.html_safe : super
+ exception.is_a?(MissingTranslation) ? super.html_safe : super
end
}
end
@@ -22,7 +22,7 @@ module TranslationHelper
# Delegates to I18n#translate but also performs three additional functions.
#
# First, it'll pass the :rescue_format => :html option to I18n so that any caught
- # MissingTranslationData exceptions will be turned into inline spans that
+ # MissingTranslation exceptions will be turned into inline spans that
#
# * have a "translation-missing" class set,
# * contain the missing key as a title attribute and
@@ -5,6 +5,13 @@ def setup
I18n.backend = I18n::Backend::Simple.new
end
+ test "throw message: MissingTranslation message from #translate includes the given scope and full key" do
+ exception = catch(:exception) do
+ I18n.t(:'baz.missing', :scope => :'foo.bar', :throw => true)
+ end
+ assert_equal "translation missing: en.foo.bar.baz.missing", exception.message
+ end
+
test "exceptions: MissingTranslationData message from #translate includes the given scope and full key" do
begin
I18n.t(:'baz.missing', :scope => :'foo.bar', :raise => true)
View
@@ -197,8 +197,8 @@ def setup
test "can use a lambda as an exception handler" do
begin
previous_exception_handler = I18n.exception_handler
- I18n.exception_handler = Proc.new { |exception, locale, key, options| exception }
- assert_equal I18n::MissingTranslationData, I18n.translate(:test_proc_handler).class
+ I18n.exception_handler = Proc.new { |exception, locale, key, options| key }
+ assert_equal :test_proc_handler, I18n.translate(:test_proc_handler)
ensure
I18n.exception_handler = previous_exception_handler
end
@@ -208,9 +208,9 @@ def setup
begin
previous_exception_handler = I18n.exception_handler
I18n.exception_handler = Class.new do
- def call(exception, locale, key, options); exception; end
+ def call(exception, locale, key, options); key; end
end.new
- assert_equal I18n::MissingTranslationData, I18n.translate(:test_proc_handler).class
+ assert_equal :test_proc_handler, I18n.translate(:test_proc_handler)
ensure
I18n.exception_handler = previous_exception_handler
end

0 comments on commit 9d85541

Please sign in to comment.