From f32daa96ab7be2d8f2a19966ed768b4307642a8f Mon Sep 17 00:00:00 2001 From: Vishnu Narayanan Date: Tue, 25 Mar 2025 00:36:40 +0530 Subject: [PATCH] fix: improve apm error reporting Previously, errors were only being logged with logger.info and rendered as JSON responses, but weren't being properly reported to APM services. This meant that critical errors like 500s were only visible in application logs but not in our monitoring systems, making it harder to track and debug issues in production. This commit ensures that all errors are properly reported to configured APM services by: 1. Adding explicit APM error reporting alongside logging 2. Using proper APM reporting methods for each service 3. Maintaining consistent error handling across all APM integrations These changes ensure that errors are properly captured in our monitoring systems,improving our ability to track and debug production issues. --- .../concerns/request_exception_handler.rb | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/app/controllers/concerns/request_exception_handler.rb b/app/controllers/concerns/request_exception_handler.rb index ccab0090a..07aed94d9 100644 --- a/app/controllers/concerns/request_exception_handler.rb +++ b/app/controllers/concerns/request_exception_handler.rb @@ -23,24 +23,29 @@ module RequestExceptionHandler Current.reset end + def render_error(message, status, error = nil) + log_handled_error(error) if error + render json: { error: message }, status: status + end + def render_unauthorized(message) - render json: { error: message }, status: :unauthorized + render_error(message, :unauthorized) end def render_not_found_error(message) - render json: { error: message }, status: :not_found + render_error(message, :not_found) end def render_could_not_create_error(message) - render json: { error: message }, status: :unprocessable_entity + render_error(message, :unprocessable_entity) end def render_payment_required(message) - render json: { error: message }, status: :payment_required + render_error(message, :payment_required) end def render_internal_server_error(message) - render json: { error: message }, status: :internal_server_error + render_error(message, :internal_server_error) end def render_record_invalid(exception) @@ -57,6 +62,23 @@ module RequestExceptionHandler end def log_handled_error(exception) + return unless exception + logger.info("Handled error: #{exception.inspect}") + report_to_apms(exception) + end + + def report_to_apms(exception) + apm_reporters = { + ::NewRelic::Agent => -> { ::NewRelic::Agent.notice_error(exception) }, + ::Datadog::Tracing => -> { ::Datadog::Tracing.active_span&.set_error(exception) }, + ::ElasticAPM => -> { ::ElasticAPM.report(exception) }, + ::ScoutApm::Error => -> { ::ScoutApm::Error.capture(exception) }, + ::Sentry => -> { ::Sentry.capture_exception(exception) } + } + + apm_reporters.each do |apm_module, reporter| + reporter.call if defined?(apm_module) + end end end