From d96c24f38602398e9e378dea4743f170abf1f9c7 Mon Sep 17 00:00:00 2001 From: Steve Laing Date: Mon, 18 Mar 2024 13:46:35 +0000 Subject: [PATCH] Add custom error handler for missing i18n translations --- config/initializers/i18n.rb | 13 +++++++++++ spec/config/initializers/i18n_spec.rb | 23 +++++++++++++++++++ .../day_month_year_validator_spec.rb | 14 +++++++++-- 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 config/initializers/i18n.rb create mode 100644 spec/config/initializers/i18n_spec.rb diff --git a/config/initializers/i18n.rb b/config/initializers/i18n.rb new file mode 100644 index 00000000..6f5b0205 --- /dev/null +++ b/config/initializers/i18n.rb @@ -0,0 +1,13 @@ +module I18n + class SentryExceptionHandler + def call(exception, _locale, _key, _options) + if Rails.env.production? && exception.is_a?(MissingTranslation) + Sentry.capture_exception(exception) + else + raise exception.respond_to?(:to_exception) ? exception.to_exception : exception + end + end + end +end + +I18n.exception_handler = I18n::SentryExceptionHandler.new diff --git a/spec/config/initializers/i18n_spec.rb b/spec/config/initializers/i18n_spec.rb new file mode 100644 index 00000000..245b1e04 --- /dev/null +++ b/spec/config/initializers/i18n_spec.rb @@ -0,0 +1,23 @@ +require "rails_helper" + +RSpec.describe I18n::SentryExceptionHandler do + let(:key) { "missing.translation" } + + describe "#call" do + it "raises exceptions in non-production environments" do + expect { I18n.translate(key) }.to raise_exception(I18n::MissingTranslationData) + end + context "in production" do + before do + allow(Rails.env).to receive(:production?).and_return(true) + allow(Sentry).to receive(:capture_exception) + end + it "captures the exception in Sentry" do + I18n.translate(key) + expect(Sentry).to have_received(:capture_exception).with( + I18n::MissingTranslation.new(:en, key) + ) + end + end + end +end diff --git a/spec/validators/day_month_year_validator_spec.rb b/spec/validators/day_month_year_validator_spec.rb index 3b5c0e7b..383fa11e 100644 --- a/spec/validators/day_month_year_validator_spec.rb +++ b/spec/validators/day_month_year_validator_spec.rb @@ -10,6 +10,16 @@ class Validatable end RSpec.describe DayMonthYearValidator do + # We don't have translations for our Validatable test class + # avoid I18n::MissingTranslationData exceptions by turning off + # I18n.exception_handler for this particular spec. + around do |example| + exception_handler = I18n.exception_handler + I18n.exception_handler = nil + example.run + I18n.exception_handler = exception_handler + end + subject(:validatable) { Validatable.new(attributes) } describe "#validate" do @@ -42,7 +52,7 @@ class Validatable expect(validatable.errors[:date_attribute]).to include("is invalid") end end - + context "when the date is negative" do let(:attributes) { { day: -1, month: "6", year: "1990" } } @@ -162,7 +172,7 @@ class Validatable expect(validatable.errors[:date_attribute].first).to include("missing_day_and_year") end end - + context "when month and year are missing" do let(:attributes) { { day: "15", month: nil, year: nil } }