Module: Realuptime::Errors::Rails
- Defined in:
- lib/realuptime/errors/rails.rb
Overview
Rails integration (REA-255). Feature-detected: this file never requires "rails"; the Railtie at the bottom is defined only when ::Rails::Railtie already exists, so requiring this file outside Rails is harmless and the helpers here are testable without it.
# Gemfile
gem "realuptime-errors", require: "realuptime/errors/rails"
# config/initializers/realuptime_errors.rb (or ENV REALUPTIME_ERRORS_DSN)
Rails.application.config.realuptime_errors.dsn = "https://realuptime.io/api/errors/v1/ingest/rue_..."
Rails.application.config.realuptime_errors.release = ENV["GIT_SHA"]
What the Railtie installs, all through the ONE capture/scrub/transport path a plain init gives:
- RailsMiddleware at the outermost position of the Rack stack: an
exception that escapes, or one Rails swallowed into its own error
page (action_dispatch.exception), is reported ONCE with method,
path and the matched controller#action as the route template.
- an ActiveJob around_perform hook that reports a job's unhandled
exception with the job class as the fingerprint key and re-raises,
so retry_on / discard_on keep working exactly as before. A job that
retries reports each failed attempt; that is the honest count.
- init itself from config.realuptime_errors / ENV when the app did
not call Realuptime::Errors.init in an initializer.
Defined Under Namespace
Modules: ActiveJobExtension Classes: RailsMiddleware, Railtie
Constant Summary collapse
- FRAMEWORK_TAG =
{ "framework" => "rails" }.freeze
Class Method Summary collapse
-
.options_from(config, env = ENV, rails_env = nil) ⇒ Object
Resolves init options from config.realuptime_errors (any object answering [] or the dotted accessors) and ENV.
-
.perform_reporting(job) ⇒ Object
Reports a job's failure and re-raises.
-
.request_context(env) ⇒ Object
Rack-level context plus the matched controller#action, the grouping key Rails exposes without any user-supplied bytes.
Class Method Details
.options_from(config, env = ENV, rails_env = nil) ⇒ Object
Resolves init options from config.realuptime_errors (any object answering [] or the dotted accessors) and ENV. Returns nil when no DSN is configured anywhere, so the Railtie stays inert rather than logging on every boot of an app that has not opted in.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/realuptime/errors/rails.rb', line 97 def self.(config, env = ENV, rails_env = nil) read = lambda do |key| value = nil if config.respond_to?(:[]) value = begin config[key] rescue StandardError nil end end value = config.public_send(key) if value.nil? && config.respond_to?(key) value end dsn = read.call(:dsn) || env["REALUPTIME_ERRORS_DSN"] return nil if dsn.nil? || dsn.to_s.empty? { dsn: dsn.to_s, release: read.call(:release) || env["REALUPTIME_RELEASE"], environment: read.call(:environment) || rails_env, allow_fields: read.call(:allow_fields), send_device_info: read.call(:send_device_info).nil? ? true : read.call(:send_device_info) } end |
.perform_reporting(job) ⇒ Object
Reports a job's failure and re-raises. Usable without ActiveJob (tests, or a hand-rolled job runner): yield the work.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/realuptime/errors/rails.rb', line 66 def self.perform_reporting(job) yield rescue Exception => e # rubocop:disable Lint/RescueException begin job_name = job.class.name.to_s Realuptime::Errors.capture_exception( e, fingerprint: ["active_job", job_name, e.class.name.to_s], tags: { "framework" => "active_job", "job" => job_name } ) rescue StandardError nil end raise end |
.request_context(env) ⇒ Object
Rack-level context plus the matched controller#action, the grouping key Rails exposes without any user-supplied bytes. path_parameters VALUES (the :id etc.) are never forwarded; only the controller and action names are.
38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/realuptime/errors/rails.rb', line 38 def self.request_context(env) request = RackMiddleware.request_context(env) || {} params = env.is_a?(Hash) ? env["action_dispatch.request.path_parameters"] : nil if params.is_a?(Hash) controller = params[:controller] || params["controller"] action = params[:action] || params["action"] request["route"] = "#{controller}##{action}" if controller && action end request.empty? ? nil : request rescue StandardError nil end |