From 92ef4821320f11ae736a25a07423ef0343cc5287 Mon Sep 17 00:00:00 2001 From: 24c02 <163450896+24c02@users.noreply.github.com> Date: Mon, 29 Dec 2025 10:39:37 -0500 Subject: [PATCH] move to sentry? --- Gemfile | 3 +- Gemfile.lock | 12 +- .../api/v1/letter_queues_controller.rb | 1 - .../api/v1/warehouse_orders_controller.rb | 1 - app/controllers/application_controller.rb | 9 +- app/controllers/base_batches_controller.rb | 5 +- app/controllers/errors_controller.rb | 9 ++ app/controllers/letter/batches_controller.rb | 4 +- .../public/application_controller.rb | 5 +- app/controllers/sessions_controller.rb | 6 +- .../warehouse/batches_controller.rb | 4 +- .../warehouse/orders_controller.rb | 10 +- app/lib/snail_mail/imb.rb | 3 +- app/lib/snail_mail/qr_code_generator.rb | 5 +- app/models/letter/instant_queue.rb | 4 +- app/models/warehouse/batch.rb | 4 +- app/models/warehouse/order.rb | 4 +- app/services/geocoding_service.rb | 5 +- app/services/usps/api_service.rb | 6 +- .../errors/internal_server_error.html.erb | 112 ++++++++++++++++++ config/application.rb | 3 + config/honeybadger.yml | 34 ------ config/initializers/sentry.rb | 8 ++ config/routes.rb | 2 + public/500.html | 2 +- 25 files changed, 177 insertions(+), 84 deletions(-) create mode 100644 app/controllers/errors_controller.rb create mode 100644 app/views/errors/internal_server_error.html.erb delete mode 100644 config/honeybadger.yml create mode 100644 config/initializers/sentry.rb diff --git a/Gemfile b/Gemfile index bf20d5f..0c5b588 100644 --- a/Gemfile +++ b/Gemfile @@ -159,7 +159,8 @@ gem "ruby-openai", "~> 8.1" gem "parallel", "~> 1.26" -gem "honeybadger", "~> 5.28" +gem "sentry-ruby" +gem "sentry-rails" gem "rmagick", "~> 5.3" diff --git a/Gemfile.lock b/Gemfile.lock index 1307c03..2c0c504 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -239,9 +239,6 @@ GEM hashids (1.0.6) hashie (5.0.0) hcbv4 (0.1.1) - honeybadger (5.28.0) - logger - ostruct http (5.2.0) addressable (~> 2.8) base64 (~> 0.1) @@ -570,6 +567,12 @@ GEM rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) + sentry-rails (6.2.0) + railties (>= 5.2.0) + sentry-ruby (~> 6.2.0) + sentry-ruby (6.2.0) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) slack-notifier (2.4.0) slim (5.2.1) temple (~> 0.10.0) @@ -721,7 +724,6 @@ DEPENDENCIES good_job (~> 4.11) hashid-rails (~> 1.4) hcbv4 (~> 0.1) - honeybadger (~> 5.28) http (~> 5.2) ivymeter (~> 0.1.0) jb (~> 0.8.2) @@ -755,6 +757,8 @@ DEPENDENCIES select2-rails (~> 4.0) selectize-rails (~> 0.12.6) selenium-webdriver + sentry-rails + sentry-ruby slack-notifier (~> 2.4) slim-rails (~> 3.7) snail (~> 2.3) diff --git a/app/controllers/api/v1/letter_queues_controller.rb b/app/controllers/api/v1/letter_queues_controller.rb index bae41c6..1a65b5d 100644 --- a/app/controllers/api/v1/letter_queues_controller.rb +++ b/app/controllers/api/v1/letter_queues_controller.rb @@ -11,7 +11,6 @@ module API end rescue_from ActiveRecord::RecordInvalid do |e| - Honeybadger.notify(e) render json: { error: "Validation failed", details: e.record.errors.full_messages, diff --git a/app/controllers/api/v1/warehouse_orders_controller.rb b/app/controllers/api/v1/warehouse_orders_controller.rb index d0924d7..8b39fe7 100644 --- a/app/controllers/api/v1/warehouse_orders_controller.rb +++ b/app/controllers/api/v1/warehouse_orders_controller.rb @@ -10,7 +10,6 @@ module API end rescue_from ActiveRecord::RecordInvalid do |e| - Honeybadger.notify(e) render json: { error: "Validation failed", details: e.record.errors.full_messages, diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 84d50ac..7290636 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -4,7 +4,7 @@ class ApplicationController < ActionController::Base helper_method :current_user, :user_signed_in? - before_action :authenticate_user!, :set_honeybadger_context + before_action :authenticate_user!, :set_sentry_context def current_user @current_user ||= User.find_by(id: session[:user_id]) if session[:user_id] @@ -20,11 +20,8 @@ class ApplicationController < ActionController::Base end end - def set_honeybadger_context - Honeybadger.context({ - user_id: current_user&.id, - user_email: current_user&.email, - }) + def set_sentry_context + Sentry.set_user(id: current_user&.id, email: current_user&.email) end rescue_from Pundit::NotAuthorizedError do |e| diff --git a/app/controllers/base_batches_controller.rb b/app/controllers/base_batches_controller.rb index d28a09d..a75418e 100644 --- a/app/controllers/base_batches_controller.rb +++ b/app/controllers/base_batches_controller.rb @@ -64,10 +64,9 @@ class BaseBatchesController < ApplicationController begin @batch.run_map! rescue StandardError => e - raise Rails.logger.warn(e) - uuid = Honeybadger.notify(e) - redirect_to send("#{@batch.class.name.split("::").first.downcase}_batch_path", @batch), flash: { alert: "error mapping fields! #{e.message} (please report EID: #{uuid})" } + event_id = Sentry.capture_exception(e) + redirect_to send("#{@batch.class.name.split("::").first.downcase}_batch_path", @batch), flash: { alert: "error mapping fields! #{e.message} (error: #{event_id})" } return end redirect_to send("process_confirm_#{@batch.class.name.split("::").first.downcase}_batch_path", @batch), notice: "Field mapping saved. Please review and process your batch." diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb new file mode 100644 index 0000000..bcfa0d8 --- /dev/null +++ b/app/controllers/errors_controller.rb @@ -0,0 +1,9 @@ +class ErrorsController < ApplicationController + skip_before_action :authenticate_user! + skip_after_action :verify_authorized + + def internal_server_error + @sentry_event_id = request.env["sentry.error_event_id"] || Sentry.last_event_id + render status: :internal_server_error, formats: [:html] + end +end diff --git a/app/controllers/letter/batches_controller.rb b/app/controllers/letter/batches_controller.rb index 45ae63a..f0cb81e 100644 --- a/app/controllers/letter/batches_controller.rb +++ b/app/controllers/letter/batches_controller.rb @@ -128,8 +128,8 @@ class Letter::BatchesController < BaseBatchesController redirect_to letter_batch_path(@batch, print_now: letter_batch_params[:print_immediately]), notice: "Batch processed successfully" rescue => e - uuid = Honeybadger.notify(e) - redirect_to process_letter_batch_path(@batch), alert: "Failed to process batch: #{e.message} (please report EID: #{uuid})" + event_id = Sentry.capture_exception(e) + redirect_to process_letter_batch_path(@batch), alert: "Failed to process batch: #{e.message} (error: #{event_id})" end end end diff --git a/app/controllers/public/application_controller.rb b/app/controllers/public/application_controller.rb index 4f90848..bc15f08 100644 --- a/app/controllers/public/application_controller.rb +++ b/app/controllers/public/application_controller.rb @@ -5,9 +5,8 @@ module Public layout "public" before_action do - Honeybadger.context({ - user_id: current_public_user&.id, - user_email: current_public_user&.email, + Sentry.set_user(id: current_public_user&.id, email: current_public_user&.email) + Sentry.set_context("impersonation", { real_user_id: current_user&.id, real_user_email: current_user&.email, impersonator_user_id: session[:public_impersonator_user_id], diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 97c6b1b..f08fde4 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -6,7 +6,7 @@ class SessionsController < ApplicationController def impersonate unless current_user.admin? redirect_to root_path, alert: "you are not authorized to impersonate users. this incident has been reported :-P" - Honeybadger.notify("Impersonation attempt by #{current_user.username} to #{params[:id]}") + Sentry.capture_message("Impersonation attempt by #{current_user.username} to #{params[:id]}", level: :warning) return end @@ -44,8 +44,8 @@ class SessionsController < ApplicationController @user = User.from_hack_club_auth(auth) rescue => e Rails.logger.error "Error creating user from Hack Club Auth: #{e.message}" - uuid = Honeybadger.notify(e) - redirect_to login_path, alert: "error authenticating! (error: #{uuid})" + event_id = Sentry.capture_exception(e) + redirect_to login_path, alert: "error authenticating! (error: #{event_id})" return end diff --git a/app/controllers/warehouse/batches_controller.rb b/app/controllers/warehouse/batches_controller.rb index dc1a066..68a85b8 100644 --- a/app/controllers/warehouse/batches_controller.rb +++ b/app/controllers/warehouse/batches_controller.rb @@ -114,8 +114,8 @@ class Warehouse::BatchesController < BaseBatchesController @batch.run_map! rescue StandardError => e Rails.logger.warn(e) - uuid = Honeybadger.notify(e) - redirect_to warehouse_batch_path(@batch), flash: { alert: "Error mapping fields! #{e.message} (please report EID: #{uuid})" } + event_id = Sentry.capture_exception(e) + redirect_to warehouse_batch_path(@batch), flash: { alert: "Error mapping fields! #{e.message} (error: #{event_id})" } return end redirect_to process_confirm_warehouse_batch_path(@batch), notice: "Field mapping saved. Please review and process your batch." diff --git a/app/controllers/warehouse/orders_controller.rb b/app/controllers/warehouse/orders_controller.rb index 4bc3bfe..577b22a 100644 --- a/app/controllers/warehouse/orders_controller.rb +++ b/app/controllers/warehouse/orders_controller.rb @@ -38,11 +38,13 @@ class Warehouse::OrdersController < ApplicationController begin @warehouse_order.dispatch! rescue Zenventory::ZenventoryError => e - uuid = Honeybadger.notify(e) - redirect_to @warehouse_order, alert: "zenventory said \"#{e.message}\" (please report EID: #{uuid})" + event_id = Sentry.capture_exception(e) + redirect_to @warehouse_order, alert: "zenventory said \"#{e.message}\" (error: #{event_id})" + return rescue AASM::InvalidTransition => e - uuid = Honeybadger.notify(e) - redirect_to @warehouse_order, alert: "couldn't dispatch order! wrong state? (please report EID: #{uuid})" + event_id = Sentry.capture_exception(e) + redirect_to @warehouse_order, alert: "couldn't dispatch order! wrong state? (error: #{event_id})" + return end redirect_to @warehouse_order, flash: { success: "successfully sent to warehouse!" } end diff --git a/app/lib/snail_mail/imb.rb b/app/lib/snail_mail/imb.rb index bff4467..f015eab 100644 --- a/app/lib/snail_mail/imb.rb +++ b/app/lib/snail_mail/imb.rb @@ -26,8 +26,7 @@ module SnailMail ).barcode_letters rescue ArgumentError => e Rails.logger.warn("Bad IMb input: #{e.message} @ MID #{mailer_id} SN #{serial_number} RC #{routing_code}") - uuid = Honeybadger.notify(e) - Rails.logger.warn("IMb error (please report EID: #{uuid})") + Sentry.capture_exception(e) "" end end diff --git a/app/lib/snail_mail/qr_code_generator.rb b/app/lib/snail_mail/qr_code_generator.rb index ceed0e2..203b37c 100644 --- a/app/lib/snail_mail/qr_code_generator.rb +++ b/app/lib/snail_mail/qr_code_generator.rb @@ -36,9 +36,8 @@ module SnailMail pdf.image io, at: [x, y], width: size, height: size rescue => e Rails.logger.error("QR code generation failed: #{e.message}") - uuid = Honeybadger.notify(e) - # Fallback to a text label if QR code fails - pdf.text_box "QR Error (error: #{uuid})", at: [x, y], width: size, height: size + event_id = Sentry.capture_exception(e) + pdf.text_box "QR Error (error: #{event_id})", at: [x, y], width: size, height: size end end end diff --git a/app/models/letter/instant_queue.rb b/app/models/letter/instant_queue.rb index 468d572..36d5739 100644 --- a/app/models/letter/instant_queue.rb +++ b/app/models/letter/instant_queue.rb @@ -137,9 +137,7 @@ class Letter::InstantQueue < Letter::Queue end rescue => e Rails.logger.error("Failed to create indicium for letter #{letter.id}: #{e.message}") - Rails.logger.error(e.backtrace.join("\n")) - uuid = Honeybadger.notify(e) - raise "Failed to create indicium (please report EID: #{uuid} immediately)" + raise e end end letter diff --git a/app/models/warehouse/batch.rb b/app/models/warehouse/batch.rb index 1db7881..433308f 100644 --- a/app/models/warehouse/batch.rb +++ b/app/models/warehouse/batch.rb @@ -102,8 +102,8 @@ class Warehouse::Batch < Batch begin Zenventory.create_customer_order(update_hash) rescue Zenventory::ZenventoryError => e - uuid = Honeybadger.notify(e) - errors.add(:base, "couldn't create order, Zenventory said: #{e.message} (error: #{uuid})") + event_id = Sentry.capture_exception(e) + errors.add(:base, "couldn't create order, Zenventory said: #{e.message} (error: #{event_id})") throw(:abort) end end diff --git a/app/models/warehouse/order.rb b/app/models/warehouse/order.rb index 00abb5d..e50e0c3 100644 --- a/app/models/warehouse/order.rb +++ b/app/models/warehouse/order.rb @@ -173,8 +173,8 @@ class Warehouse::Order < ApplicationRecord }.compact_blank Zenventory.update_customer_order(zenventory_id, update_hash) unless update_hash.empty? rescue Zenventory::ZenventoryError => e - uuid = Honeybadger.notify(e) - errors.add(:base, "couldn't edit order, Zenventory said: #{e.message} (error: #{uuid})") + event_id = Sentry.capture_exception(e) + errors.add(:base, "couldn't edit order, Zenventory said: #{e.message} (error: #{event_id})") throw(:abort) end end diff --git a/app/services/geocoding_service.rb b/app/services/geocoding_service.rb index 74ef983..e108cb8 100644 --- a/app/services/geocoding_service.rb +++ b/app/services/geocoding_service.rb @@ -105,10 +105,9 @@ module GeocodingService key: ENV["HACKCLUB_GEOCODER_API_KEY"], }) - # Handle error responses if response.body.key?("error") Rails.logger.error "Hack Club Geocoder error: #{response.body["error"]}" - Honeybadger.notify("Geocoding error: #{response.body["error"]}") + Sentry.capture_message("Geocoding error: #{response.body["error"]}") return nil end @@ -123,7 +122,7 @@ module GeocodingService } rescue => e Rails.logger.error "Hack Club Geocoder request failed: #{e.message}" - Honeybadger.notify(e) + Sentry.capture_exception(e) nil end diff --git a/app/services/usps/api_service.rb b/app/services/usps/api_service.rb index 96bca94..33e0881 100644 --- a/app/services/usps/api_service.rb +++ b/app/services/usps/api_service.rb @@ -34,16 +34,14 @@ module FaradayMiddleware def on_complete(env) unless env.response.success? unless env.response.body.respond_to?(:dig) - uuid = Honeybadger.notify(USPS::USPSError.new(env.response.body)) - raise USPS::USPSError, "#{env.response.body} (please report EID: #{uuid})" + raise USPS::USPSError, env.response.body.to_s end if env.response.body.dig(:error, :message) == "Address Not Found." raise USPS::NxAddress elsif env.response.body.dig(:error, :message) == "Invalid Zip Code." raise USPS::NxZIP else - uuid = Honeybadger.notify(USPS::USPSError.new(env.response.body)) - raise USPS::USPSError, "#{env.response.body} (please report EID: #{uuid})" + raise USPS::USPSError, env.response.body.to_s end end end diff --git a/app/views/errors/internal_server_error.html.erb b/app/views/errors/internal_server_error.html.erb new file mode 100644 index 0000000..f16827a --- /dev/null +++ b/app/views/errors/internal_server_error.html.erb @@ -0,0 +1,112 @@ + + + + + + + error!! + + + + +
+
+ +
+

ERROR 500

+

+ An internal server error has occurred.
+ Please poke @nora with the + following error ID and what you were trying to do when this happened. +

+ <% if @sentry_event_id.present? %> +

+ Error ID:<%= @sentry_event_id %> + (click to copy) +

+ <% end %> + <- return to homepage +
+ + + diff --git a/config/application.rb b/config/application.rb index 1d725ba..7e2053d 100644 --- a/config/application.rb +++ b/config/application.rb @@ -45,5 +45,8 @@ module Theseus expire_after: 30.days, secure: Rails.env.production?, httponly: true + + # Use dynamic error pages so we can show Sentry event IDs + config.exceptions_app = routes end end diff --git a/config/honeybadger.yml b/config/honeybadger.yml deleted file mode 100644 index f0feaec..0000000 --- a/config/honeybadger.yml +++ /dev/null @@ -1,34 +0,0 @@ ---- -# For more options, see https://docs.honeybadger.io/lib/ruby/gem-reference/configuration - -api_key: '<%= ENV["HONEYBADGER_API_KEY"] %>' - -# The environment your app is running in. -env: "<%= Rails.env %>" - -# The absolute path to your project folder. -root: "<%= Rails.root.to_s %>" - -# Honeybadger won't report errors in these environments. -development_environments: -- test -- development -- cucumber - -# By default, Honeybadger won't report errors in the development_environments. -# You can override this by explicitly setting report_data to true or false. -# report_data: true - -# The current Git revision of your project. Defaults to the last commit hash. -# revision: null - -# Enable verbose debug logging (useful for troubleshooting). -debug: false - -# Enable Honeybadger Insights -insights: - enabled: false - -user_informer: - enabled: true - info: "{{error_id}}" \ No newline at end of file diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb new file mode 100644 index 0000000..a62edaa --- /dev/null +++ b/config/initializers/sentry.rb @@ -0,0 +1,8 @@ +Sentry.init do |config| + config.dsn = ENV["SENTRY_DSN"] + config.breadcrumbs_logger = [:active_support_logger, :http_logger] + config.enabled_environments = %w[production staging] + config.send_default_pii = true + + config.traces_sample_rate = 0.1 +end diff --git a/config/routes.rb b/config/routes.rb index 5ae4c0f..b6ec3df 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -704,6 +704,8 @@ Rails.application.routes.draw do end end + match "/500", to: "errors#internal_server_error", via: :all + # Render dynamic PWA files from app/views/pwa/* (remember to link manifest in application.html.erb) # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker diff --git a/public/500.html b/public/500.html index 55eb910..2f0cc5d 100644 --- a/public/500.html +++ b/public/500.html @@ -100,7 +100,7 @@

Error ID: + onclick="navigator.clipboard.writeText(this.textContent); this.textContent = 'copied!'"> (click to copy)

<- return to homepage