From 03db3e48abad235488c887fed86eaa8179f4b379 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20V=C3=A1squez?= Date: Thu, 9 Jul 2026 13:40:50 -0600 Subject: [PATCH] Integrate Sentry for exception tracking (#61) Report unhandled exceptions to Sentry in production instead of only logging them. sentry-rails auto-installs the Rack/Rails middleware, so no controller changes are needed. - Add sentry-ruby + sentry-rails (production group) - config/initializers/sentry.rb: prod-only Sentry.init, DSN from ENV["SENTRY_DSN"], no-op when the DSN is absent - .env.sample: SENTRY_DSN placeholder - Update both lockfiles (dual-boot) send_default_pii left off (default) to avoid shipping client IPs and request data to a third party, per the app's privacy policy. --- .env.sample | 1 + Gemfile | 8 ++++++++ Gemfile.lock | 9 +++++++++ Gemfile.next.lock | 9 +++++++++ config/initializers/sentry.rb | 10 ++++++++++ 5 files changed, 37 insertions(+) create mode 100644 config/initializers/sentry.rb diff --git a/.env.sample b/.env.sample index 39c032f..75050fd 100644 --- a/.env.sample +++ b/.env.sample @@ -2,3 +2,4 @@ AWS_BUCKET= AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= EXECJS_RUNTIME=Node +SENTRY_DSN= diff --git a/Gemfile b/Gemfile index 5fc1289..91f8546 100644 --- a/Gemfile +++ b/Gemfile @@ -76,4 +76,12 @@ group :development do gem "spring-watcher-listen", "~> 2.1.0" end +# Exception tracking. Reports unhandled exceptions to Sentry in production; +# the DSN is supplied via the SENTRY_DSN env var (see .env.sample). sentry-rails +# auto-installs the Rack/Rails middleware, so no controller changes are needed. +group :production do + gem "sentry-ruby" + gem "sentry-rails" +end + gem "tzinfo-data", platforms: [:windows, :jruby] diff --git a/Gemfile.lock b/Gemfile.lock index 0e41380..dd9ad73 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -368,6 +368,13 @@ GEM rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) + sentry-rails (6.6.2) + railties (>= 5.2.0) + sentry-ruby (~> 6.6.2) + sentry-ruby (6.6.2) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + logger spring (4.7.0) spring-watcher-listen (2.1.0) listen (>= 2.7, < 4.0) @@ -438,6 +445,8 @@ DEPENDENCIES rubocop-rails-omakase sass-rails (~> 6.0) selenium-webdriver + sentry-rails + sentry-ruby spring spring-watcher-listen (~> 2.1.0) terser diff --git a/Gemfile.next.lock b/Gemfile.next.lock index 0e41380..dd9ad73 100644 --- a/Gemfile.next.lock +++ b/Gemfile.next.lock @@ -368,6 +368,13 @@ GEM rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) + sentry-rails (6.6.2) + railties (>= 5.2.0) + sentry-ruby (~> 6.6.2) + sentry-ruby (6.6.2) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + logger spring (4.7.0) spring-watcher-listen (2.1.0) listen (>= 2.7, < 4.0) @@ -438,6 +445,8 @@ DEPENDENCIES rubocop-rails-omakase sass-rails (~> 6.0) selenium-webdriver + sentry-rails + sentry-ruby spring spring-watcher-listen (~> 2.1.0) terser diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb new file mode 100644 index 0000000..f5d87dc --- /dev/null +++ b/config/initializers/sentry.rb @@ -0,0 +1,10 @@ +if Rails.env.production? && ENV["SENTRY_DSN"].present? + Sentry.init do |config| + config.dsn = ENV["SENTRY_DSN"] + config.breadcrumbs_logger = [:active_support_logger, :http_logger] + + # Capture 100% of transactions for performance tracing. Lower this if the + # volume becomes noisy or the Sentry quota gets tight. + config.traces_sample_rate = 1.0 + end +end