Summary
Decidim::TermCustomizer::I18nBackend::Implementation#available_locales only rescues ActiveRecord::StatementInvalid.
- But
ActiveRecord::ConnectionNotEstablished is not rescued when the application cannot connect to the database.
- This causes problems in environments without a database, for example when running
assets:precompile while building a Docker image.
Current implementation
|
# Get available locales from the translations hash |
|
def available_locales |
|
Translation.available_locales |
|
rescue ::ActiveRecord::StatementInvalid |
|
[] |
|
end |
This backend is added to I18n::Backend::Chain in the engine initializer.
Therefore, a database query can happen whenever I18n.available_locales is called.
Why the current rescue is not enough
In the ActiveRecord exception hierarchy, ConnectionNotEstablished is not a subclass of StatementInvalid.
ActiveRecord::ActiveRecordError
└─ AdapterError
├─ StatementInvalid # rescued
│ ├─ NoDatabaseError # rescued
│ └─ QueryAborted
│ └─ ConnectionFailed # rescued
└─ ConnectionNotEstablished # not rescued
└─ DatabaseConnectionError # not rescued
Cases already handled
- The database table does not exist because migrations have not been run ->
StatementInvalid
- The database itself does not exist ->
NoDatabaseError
Case not handled
- A connection to the database cannot be established ->
ConnectionNotEstablished
The last case can happen while building a container, or in a CI environment without database credentials.
Steps to reproduce
- Create a Decidim application with
decidim-term_customizer.
- Make the database unreachable, for example by stopping the database server or setting
DATABASE_URL to a non-existing host.
- Run:
bin/rails runner 'I18n.available_locales'
The same issue also occurs with:
bin/rails assets:precompile
ActiveRecord::ConnectionNotEstablished is propagated from available_locales, and the process fails.
Expected behavior
The term customizer backend returns no locales, and the process continues.
Summary
Decidim::TermCustomizer::I18nBackend::Implementation#available_localesonly rescuesActiveRecord::StatementInvalid.ActiveRecord::ConnectionNotEstablishedis not rescued when the application cannot connect to the database.assets:precompilewhile building a Docker image.Current implementation
decidim-module-term_customizer/lib/decidim/term_customizer/i18n_backend.rb
Lines 15 to 20 in ae8e832
This backend is added to
I18n::Backend::Chainin the engine initializer.Therefore, a database query can happen whenever
I18n.available_localesis called.Why the current rescue is not enough
In the ActiveRecord exception hierarchy,
ConnectionNotEstablishedis not a subclass ofStatementInvalid.Cases already handled
StatementInvalidNoDatabaseErrorCase not handled
ConnectionNotEstablishedThe last case can happen while building a container, or in a CI environment without database credentials.
Steps to reproduce
decidim-term_customizer.DATABASE_URLto a non-existing host.bin/rails runner 'I18n.available_locales'The same issue also occurs with:
ActiveRecord::ConnectionNotEstablishedis propagated fromavailable_locales, and the process fails.Expected behavior
The term customizer backend returns no locales, and the process continues.