Class: ErrorReporting
- Inherits:
-
Object
- Object
- ErrorReporting
- Defined in:
- app/services/error_reporting.rb
Overview
ErrorReporting - Unified error reporting abstraction
Provides a consistent interface for error reporting that can route to
different providers (AppSignal, Rollbar, etc.) without changing call sites.
Namespace Structure (9 namespaces total):
Aligned with AppSignal's default namespaces (web, background, frontend)
| Source | Severity | Namespace | Notification |
|---|---|---|---|
| Rails | Error | web | First in Deploy |
| Rails | Warning | web_warning | First Occurrence |
| Rails | Info | web_info | Never Notify |
| JavaScript | Error | frontend | First in Deploy |
| JavaScript | Warning | frontend_warning | First Occurrence |
| JavaScript | Info | frontend_info | Never Notify |
| Sidekiq | Error | background | First in Deploy |
| Sidekiq | Warning | background_warning | First Occurrence |
| Sidekiq | Info | background_info | Never Notify |
Usage:
From a controller
ErrorReporting.from_controller(self).error(exception)
ErrorReporting.from_controller(self).warning(exception)
ErrorReporting.from_controller(self).informational(exception)
From a worker (uses 'background' namespace family)
ErrorReporting.error(exception, source: :background)
ErrorReporting.warning(exception, source: :background)
Direct calls default to 'web' namespace family
ErrorReporting.error(exception)
ErrorReporting.warning("Unusual condition", { value: x })
ErrorReporting.informational("Expected condition", { reason: 'bot' })
Info/debug (logs only, not sent to AppSignal)
ErrorReporting.info("Process completed", { count: 100 })
Defined Under Namespace
Classes: ControllerReporter
Class Method Summary collapse
-
.critical(exception_or_message, context = {}) ⇒ Object
Report a critical error (more severe than error) Goes to base namespace with critical severity tag.
-
.debug(message, context = {}) ⇒ Object
Report debug level.
-
.enabled? ⇒ Boolean
Check if error reporting is enabled.
-
.error(exception_or_message, context = {}) ⇒ Object
Report an error (exception or message string) Goes to namespace based on source (e.g., web, frontend, background).
-
.from_controller(controller) ⇒ ControllerReporter
Create a reporter with controller context for richer error data.
-
.info(message, context = {}) ⇒ Object
Report info level (logs only, does not send to AppSignal) For operational messages that don't need tracking in error monitoring.
-
.informational(message_or_exception, context = {}) ⇒ Object
Report an informational event (expected conditions worth tracking) Goes to namespace_info - configure "Never Notify" in AppSignal Use for: bot detection, CSRF failures, record not found, routing errors.
-
.provider ⇒ Object
Get the current provider name.
-
.scoped(context = {}) ⇒ Object
(also: with_context)
Execute block with additional context for error reports Context is thread-local and automatically cleared after the block.
-
.track(name, context = {}) ⇒ Object
Track a custom event/metric.
-
.warning(message_or_exception, context = {}) ⇒ Object
Report a warning (less severe than error) Goes to namespace_warning (e.g., web_warning, background_warning).
Class Method Details
.critical(exception_or_message, context = {}) ⇒ Object
Report a critical error (more severe than error)
Goes to base namespace with critical severity tag
81 82 83 84 85 86 87 88 |
# File 'app/services/error_reporting.rb', line 81 def critical(, context = {}) context = normalize_context(context) context[:severity] = 'critical' exception = normalize_exception() namespace = build_namespace(context) send_to_provider(exception, context: context, namespace: namespace) log_error(exception, context, :critical) end |
.debug(message, context = {}) ⇒ Object
Report debug level
115 116 117 118 |
# File 'app/services/error_reporting.rb', line 115 def debug(, context = {}) context = normalize_context(context) Rails.logger.debug { "[ErrorReporting] #{}#{context_suffix(context)}" } end |
.enabled? ⇒ Boolean
Check if error reporting is enabled
148 149 150 151 152 |
# File 'app/services/error_reporting.rb', line 148 def enabled? return false if Rails.env.test? appsignal_available? end |
.error(exception_or_message, context = {}) ⇒ Object
Report an error (exception or message string)
Goes to namespace based on source (e.g., web, frontend, background)
57 58 59 60 61 62 63 |
# File 'app/services/error_reporting.rb', line 57 def error(, context = {}) context = normalize_context(context) exception = normalize_exception() namespace = build_namespace(context) send_to_provider(exception, context: context, namespace: namespace) log_error(exception, context, :error) end |
.from_controller(controller) ⇒ ControllerReporter
Create a reporter with controller context for richer error data
48 49 50 |
# File 'app/services/error_reporting.rb', line 48 def from_controller(controller) ControllerReporter.new(controller) end |
.info(message, context = {}) ⇒ Object
Report info level (logs only, does not send to AppSignal)
For operational messages that don't need tracking in error monitoring
107 108 109 110 |
# File 'app/services/error_reporting.rb', line 107 def info(, context = {}) context = normalize_context(context) Rails.logger.info("[ErrorReporting] #{}#{context_suffix(context)}") end |
.informational(message_or_exception, context = {}) ⇒ Object
Report an informational event (expected conditions worth tracking)
Goes to namespace_info - configure "Never Notify" in AppSignal
Use for: bot detection, CSRF failures, record not found, routing errors
95 96 97 98 99 100 101 |
# File 'app/services/error_reporting.rb', line 95 def informational(, context = {}) context = normalize_context(context) exception = normalize_exception() namespace = build_namespace(context, suffix: 'info') send_to_provider(exception, context: context, namespace: namespace) log_info(exception, context) end |
.provider ⇒ Object
Get the current provider name
155 156 157 158 159 160 161 |
# File 'app/services/error_reporting.rb', line 155 def provider if appsignal_available? :appsignal else :none end end |
.scoped(context = {}) ⇒ Object Also known as: with_context
Execute block with additional context for error reports
Context is thread-local and automatically cleared after the block
136 137 138 139 140 141 142 |
# File 'app/services/error_reporting.rb', line 136 def scoped(context = {}, &) previous_context = Thread.current[:error_reporting_context] || {} Thread.current[:error_reporting_context] = previous_context.merge(context) yield ensure Thread.current[:error_reporting_context] = previous_context end |
.track(name, context = {}) ⇒ Object
Track a custom event/metric
123 124 125 126 127 128 129 130 131 |
# File 'app/services/error_reporting.rb', line 123 def track(name, context = {}) context = normalize_context(context) if appsignal_available? Appsignal.instrument(name) do # No-op block, just for tracking end end Rails.logger.info("[ErrorReporting.track] #{name}#{context_suffix(context)}") end |
.warning(message_or_exception, context = {}) ⇒ Object
Report a warning (less severe than error)
Goes to namespace_warning (e.g., web_warning, background_warning)
69 70 71 72 73 74 75 |
# File 'app/services/error_reporting.rb', line 69 def warning(, context = {}) context = normalize_context(context) exception = normalize_exception() namespace = build_namespace(context, suffix: 'warning') send_to_provider(exception, context: context, namespace: namespace) log_warning(exception, context) end |