Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ERROR] request#show (NoMethodError) "undefined method `strip' for nil:NilClass" #5382

Closed
garethrees opened this issue Sep 30, 2019 · 8 comments · Fixed by #5893
Closed

[ERROR] request#show (NoMethodError) "undefined method `strip' for nil:NilClass" #5382

garethrees opened this issue Sep 30, 2019 · 8 comments · Fixed by #5893
Labels

Comments

@garethrees
Copy link
Member

A NoMethodError occurred in request#show:

undefined method `strip' for nil:NilClass
app/models/incoming_message.rb:260:in `specific_from_name?'


-------------------------------
Request:
-------------------------------

* URL : https://transparencia.be/nl_BE/request/demande_de_la_composition_de
* HTTP Method: GET
* Parameters : {"controller"=>"request", "action"=>"show", "url_title"=>"demande_de_la_composition_de", "locale"=>"nl_BE"}
* Timestamp : 2019-09-29 02:03:37 +0200
* Server : owl
* Rails root : /REDACTED/alaveteli-2019-09-02T14-26-17

-------------------------------
Backtrace:
-------------------------------

app/models/incoming_message.rb:260:in `specific_from_name?'
app/views/request/_incoming_correspondence.html.erb:4:in `_app_views_request__incoming_correspondence_html_erb__3894700621597723031_70052969946440'
app/views/request/_correspondence.html.erb:4:in `_app_views_request__correspondence_html_erb___2880736604165700046_70052975628640'
app/views/request/show.html.erb:70:in `block in _app_views_request_show_html_erb___4362884285142867874_70052978526160'
app/views/request/show.html.erb:68:in `_app_views_request_show_html_erb___4362884285142867874_70052978526160'
app/controllers/request_controller.rb:133:in `block (3 levels) in show'
app/controllers/request_controller.rb:132:in `block in show'
lib/alaveteli_localization.rb:43:in `with_locale'
app/controllers/request_controller.rb:83:in `show'
app/controllers/application_controller.rb:115:in `record_memory'
lib/strip_empty_sessions.rb:13:in `call'
@garethrees garethrees added bug Breaks expected functionality x:belgium f:request-management labels Sep 30, 2019
@garethrees
Copy link
Member Author

This only happens in an alternative locale:

r = InfoRequest.find_by url_title: 'demande_de_la_composition_de'

r.incoming_messages.last.specific_from_name?
# => true

AlaveteliLocalization.with_locale('nl_BE') { r.incoming_messages.last.specific_from_name? }
# => NoMethodError: undefined method `strip' for nil:NilClass

@garethrees
Copy link
Member Author

Lets look at what's going on here:

# class IncomingMessage…
  def specific_from_name?
    !safe_mail_from.nil? && safe_mail_from.strip != info_request.public_body.name.strip
  end

We have a safe_mail_from:

m = r.incoming_messages.last
m.safe_mail_from
# => "Info Controleorgaan"

But we only have a PublicBody#name for the default locale…

m.info_request.public_body.name
# => "Organe de controle de l'information policière"

AlaveteliLocalization.with_locale('nl_BE') { m.info_request.public_body.name }
# => nil

…so we're trying to call strip on nil.

@garethrees
Copy link
Member Author

I think this is actually a problem with underscore locales.

When we have a PublicBody with only the default translation, with non-underscore translations we get a fallback:

b.translated_locales
# => [:en]

b.name(:en)
# => "Foo"

b.name(:es)
# => "Foo"

With underscore locales, we don't get the fallback:

b.translated_locales
# => [:fr_BE]

b.name(:fr_BE)
# => "Organe de controle de l'information policière"

b.name(:nl_BE)
# => nil

@garethrees
Copy link
Member Author

garethrees commented Oct 2, 2019

I think this is actually a problem with underscore locales.

Yep. In this case, :nl_BE is not falling back to :fr_BE:

I18n.fallbacks
# => { :fr_BE => [:fr_BE, :"fr-BE", :fr],
#      :nl_BE => [:nl_BE, :"fr-BE", :fr] }

AlaveteliLocalization.with_locale(:fr_BE) { Globalize.fallbacks }
# => [:fr_BE, :"fr-BE", :fr]
AlaveteliLocalization.with_locale(:nl_BE) { Globalize.fallbacks }
# => [:nl_BE, :"fr-BE", :fr]

@garethrees
Copy link
Member Author

Manually including :fr_BE in the Globalize.fallbacks gives us what we want:

fallbacks = {
  fr_BE: [:fr_BE, :"fr-BE", :fr],
  nl_BE: [:nl_BE, :fr_BE, :"fr-BE", :fr]
}

Globalize.fallbacks = fallbacks
# => {:fr_BE=>[:fr_BE, :"fr-BE", :fr], :nl_BE=>[:nl_BE, :fr_BE, :"fr-BE", :fr]}

b.name(:fr_BE)
# => "Organe de controle de l'information policière"
b.name(:nl_BE)
# => "Organe de controle de l'information policière"

@garethrees
Copy link
Member Author

garethrees commented Sep 23, 2020

Also seeing these in Rwanda (likely because it has an underscore locale as the default locale). Similar cause as #5890. More info in https://github.com/mysociety/alaveteli/wiki/Translations-and-underscore-locales.

mysociety-pusher pushed a commit that referenced this issue Sep 23, 2020
When a site has an underscore locale (e.g. "fr_BE") set as the default,
it is not included in the I18n fallbacks for non-default locales.

    I18n.fallbacks
    # => { :fr_BE => [:fr_BE, :"fr-BE", :fr],
    #      :nl_BE => [:nl_BE, :"fr-BE", :fr] }

    AlaveteliLocalization.with_locale(:fr_BE) { Globalize.fallbacks }
    # => [:fr_BE, :"fr-BE", :fr]
    AlaveteliLocalization.with_locale(:nl_BE) { Globalize.fallbacks }
    # => [:nl_BE, :"fr-BE", :fr]

In the example above, this means that a missing model translation when
using the "nl_BE" locale will **not** correctly fall back to the
translation for the default locale ("fr_BE").

This commit ensures that the default locale is always available in the
fallbacks for non-default locales. We try to add it before the
non-underscore version so that the regional translation is preferred,
with the non-regional fallback available as a last-ditch attempt to find
a useful translation.

Fixes #5382
mysociety-pusher pushed a commit that referenced this issue Sep 23, 2020
When a site has an underscore locale (e.g. "fr_BE") set as the default,
it is not included in the I18n fallbacks for non-default locales.

    I18n.fallbacks
    # => { :fr_BE => [:fr_BE, :"fr-BE", :fr],
    #      :nl_BE => [:nl_BE, :"fr-BE", :fr] }

    AlaveteliLocalization.with_locale(:fr_BE) { Globalize.fallbacks }
    # => [:fr_BE, :"fr-BE", :fr]
    AlaveteliLocalization.with_locale(:nl_BE) { Globalize.fallbacks }
    # => [:nl_BE, :"fr-BE", :fr]

In the example above, this means that a missing model translation when
using the "nl_BE" locale will **not** correctly fall back to the
translation for the default locale ("fr_BE").

This commit ensures that the default locale is always available in the
fallbacks for non-default locales. We try to add it before the
non-underscore version so that the regional translation is preferred,
with the non-regional fallback available as a last-ditch attempt to find
a useful translation.

Fixes #5382
mysociety-pusher pushed a commit that referenced this issue Sep 24, 2020
When a site has an underscore locale (e.g. "fr_BE") set as the default,
it is not included in the I18n fallbacks for non-default locales.

    I18n.fallbacks
    # => { :fr_BE => [:fr_BE, :"fr-BE", :fr],
    #      :nl_BE => [:nl_BE, :"fr-BE", :fr] }

    AlaveteliLocalization.with_locale(:fr_BE) { Globalize.fallbacks }
    # => [:fr_BE, :"fr-BE", :fr]
    AlaveteliLocalization.with_locale(:nl_BE) { Globalize.fallbacks }
    # => [:nl_BE, :"fr-BE", :fr]

In the example above, this means that a missing model translation when
using the "nl_BE" locale will **not** correctly fall back to the
translation for the default locale ("fr_BE").

This commit ensures that the default locale is always available in the
fallbacks for non-default locales. We try to add it before the
non-underscore version so that the regional translation is preferred,
with the non-regional fallback available as a last-ditch attempt to find
a useful translation.

Fixes #5382
mysociety-pusher pushed a commit that referenced this issue Sep 24, 2020
When a site has an underscore locale (e.g. "fr_BE") set as the default,
it is not included in the I18n fallbacks for non-default locales.

    I18n.fallbacks
    # => { :fr_BE => [:fr_BE, :"fr-BE", :fr],
    #      :nl_BE => [:nl_BE, :"fr-BE", :fr] }

    AlaveteliLocalization.with_locale(:fr_BE) { Globalize.fallbacks }
    # => [:fr_BE, :"fr-BE", :fr]
    AlaveteliLocalization.with_locale(:nl_BE) { Globalize.fallbacks }
    # => [:nl_BE, :"fr-BE", :fr]

In the example above, this means that a missing model translation when
using the "nl_BE" locale will **not** correctly fall back to the
translation for the default locale ("fr_BE").

This commit ensures that the default locale is always available in the
fallbacks for non-default locales. We try to add it before the
non-underscore version so that the regional translation is preferred,
with the non-regional fallback available as a last-ditch attempt to find
a useful translation.

Fixes #5382
mysociety-pusher pushed a commit that referenced this issue Sep 24, 2020
When a site has an underscore locale (e.g. "fr_BE") set as the default,
it is not included in the I18n fallbacks for non-default locales.

    I18n.fallbacks
    # => { :fr_BE => [:fr_BE, :"fr-BE", :fr],
    #      :nl_BE => [:nl_BE, :"fr-BE", :fr] }

    AlaveteliLocalization.with_locale(:fr_BE) { Globalize.fallbacks }
    # => [:fr_BE, :"fr-BE", :fr]
    AlaveteliLocalization.with_locale(:nl_BE) { Globalize.fallbacks }
    # => [:nl_BE, :"fr-BE", :fr]

In the example above, this means that a missing model translation when
using the "nl_BE" locale will **not** correctly fall back to the
translation for the default locale ("fr_BE").

This commit ensures that the default locale is always available in the
fallbacks for non-default locales. We try to add it before the
non-underscore version so that the regional translation is preferred,
with the non-regional fallback available as a last-ditch attempt to find
a useful translation.

Globalize model attributes fallbacks specs contributed by @gbp.

Fixes #5382
Fixes #5895
mysociety-pusher pushed a commit that referenced this issue Sep 24, 2020
When a site has an underscore locale (e.g. "fr_BE") set as the default,
it is not included in the I18n fallbacks for non-default locales.

    I18n.fallbacks
    # => { :fr_BE => [:fr_BE, :"fr-BE", :fr],
    #      :nl_BE => [:nl_BE, :"fr-BE", :fr] }

    AlaveteliLocalization.with_locale(:fr_BE) { Globalize.fallbacks }
    # => [:fr_BE, :"fr-BE", :fr]
    AlaveteliLocalization.with_locale(:nl_BE) { Globalize.fallbacks }
    # => [:nl_BE, :"fr-BE", :fr]

In the example above, this means that a missing model translation when
using the "nl_BE" locale will **not** correctly fall back to the
translation for the default locale ("fr_BE").

This commit ensures that the default locale is always available in the
fallbacks for non-default locales. We try to add it before the
non-underscore version so that the regional translation is preferred,
with the non-regional fallback available as a last-ditch attempt to find
a useful translation.

Globalize model attributes fallbacks specs contributed by @gbp.

Fixes #5382
Fixes #5895
@gbp
Copy link
Member

gbp commented Jan 26, 2022

Seeing this more on Rwanda since bumping to 0.40 and/or migrating to the new infra.

@gbp gbp reopened this Jan 26, 2022
@gbp
Copy link
Member

gbp commented Feb 8, 2022

This has an issue again since 02ea505 but only visible for us at mySociety since upgrading Belgium and Rwanda to 0.40. Both these sites have underscored locales (fr_BE nl_BE and en_RW rw fr)

It turns out calling AlaveteliLocalization.set_locales in a config.before_configuration block doesn't persist correctly and is really needed in an config.after_initialize block.

Unfortunately we can't move to an after_initialize hook as this leads to an error when booting Rails 6.1 in development mode. This due Alaveteli not yet using the new Zeitwork autoloading feature and Rails attempts to render a deprecation warning which happens to includes an I18n translation so requires the default locale to be setup.

@gbp gbp closed this as completed in cfd0caa Feb 9, 2022
gbp added a commit that referenced this issue Jan 8, 2025
gbp added a commit that referenced this issue Jan 8, 2025
gbp added a commit that referenced this issue Jan 8, 2025
gbp added a commit that referenced this issue Jan 9, 2025
gbp added a commit that referenced this issue Jan 10, 2025
Sometimes we need locales to be loaded before the application has been
initialised.

Setting in the in `config.before_configuration` block doesn't persist
correctly and also needs to be called in after initialisation.

This issue became apparent when there is an exception on boot. The error
message might call `to_sentence` [1], which will load a translation and
this then error if `set_locales` hasn't been called.

[1]: https://github.com/rails/rails/blob/d39db5d/activestorage/lib/active_storage/service/registry.rb#L18-L19

See #5382
gbp added a commit that referenced this issue Jan 13, 2025
Sometimes we need locales to be loaded before the application has been
initialised.

Setting in the in `config.before_configuration` block doesn't persist
correctly and also needs to be called in after initialisation.

This issue becomes apparent when there is an exception at boot.

The error message might call `to_sentence` [1], which will attempt to
load a translation and this then error if `set_locales` hasn't been
called.

[1]: https://github.com/rails/rails/blob/d39db5d/activestorage/lib/active_storage/service/registry.rb#L18-L19

See #5382
gbp added a commit that referenced this issue Jan 13, 2025
Sometimes we need locales to be loaded before the application has been
initialised.

Setting in the in `config.before_configuration` block doesn't persist
correctly and also needs to be called in after initialisation.

This issue becomes apparent when there is an exception at boot.

The error message might call `to_sentence` [1], which will attempt to
load a translation and this then error if `set_locales` hasn't been
called.

[1]: https://github.com/rails/rails/blob/d39db5d/activestorage/lib/active_storage/service/registry.rb#L18-L19

See #5382
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants