Skip to content

I18n::MissingTranslationData: Translation missing: en.faker.company.buzzwords (I18n::MissingTranslationData) #2987

@rocket-turtle

Description

@rocket-turtle

Describe the bug

With my Setup I get this error when I call: Faker::Company.catch_phrase

I18n::MissingTranslationData: Translation missing: en.faker.company.buzzwords (I18n::MissingTranslationData)

    raise exception.respond_to?(:to_exception) ? exception.to_exception : exception
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

i18n-1.14.5/lib/i18n.rb:423:in handle_exception' i18n-1.14.5/lib/i18n.rb:396:in translate_key'
i18n-1.14.5/lib/i18n.rb:222:in translate' faker-3.4.2/lib/faker.rb:173:in block in translate'
faker-3.4.2/lib/faker.rb:265:in disable_enforce_available_locales' faker-3.4.2/lib/faker.rb:172:in rescue in translate'
faker-3.4.2/lib/faker.rb:162:in translate' faker-3.4.2/lib/faker/default/company.rb:57:in catch_phrase'

To Reproduce

Describe a way to reproduce your bug. To get the Faker version, run Faker::VERSION.

Use the reproduction script below to reproduce the issue:

# frozen_string_literal: true

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  gem 'faker', :git => 'https://github.com/faker-ruby/faker.git', :branch => 'main'
  gem "minitest"
end

require "minitest/autorun"
I18n.available_locales = [:de]

class BugTest < Minitest::Test
  def test_faker
    phrase = Faker::Company.catch_phrase
    assert phrase.is_a?(String)
  end
end

Additional context

I18n.enforce_available_locales => true
I18n.locale_available?(:en) => false
I18n.backend.send(:translations).keys => [:de]

Faker has a real simple translation missing fallback:

faker-3.4.2/lib/faker.rb

      # Call I18n.translate with our configured locale if no
      # locale is specified
      def translate(*args, **opts)
        opts[:locale] ||= Faker::Config.locale
        opts[:raise] = true
        I18n.translate(*args, **opts)
      rescue I18n::MissingTranslationData
        opts[:locale] = :en

        # Super-simple fallback -- fallback to en if the
        # translation was missing.  If the translation isn't
        # in en either, then it will raise again.
        disable_enforce_available_locales do
          I18n.translate(*args, **opts)
        end
      end

The disable_enforce_available_locales try to fix, if enforce_available_locales is set but :en is not in the i18n.available_locales.

faker-3.4.2/lib/faker.rb:262

      def disable_enforce_available_locales
        old_enforce_available_locales = I18n.enforce_available_locales
        I18n.enforce_available_locales = false
        yield
      ensure
        I18n.enforce_available_locales = old_enforce_available_locales
      end

Problem

With this setup I18n does not store the :en translation.

i18n-1.14.5/lib/i18n/backend/simple.rb

        def store_translations(locale, data, options = EMPTY_HASH)
          if I18n.enforce_available_locales &&
            I18n.available_locales_initialized? &&
            !I18n.locale_available?(locale)
            return data
          end

Current workaround

Somewhere in my code I make: I18n.reload! if I18n.backend.send(:translations).keys.exclude?(:en)

Solution?

I can not think about a good / easy solution without "polluting" the translations:

Before the reload! I18n.backend.send(:translations).keys.count => 1
After the reload! I18n.backend.send(:translations).keys.count => 66

Maybe the solution is in #2719

The only way I see this becoming faster is to remove i18n and lazy load those yaml files we need.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions