Module: Dispatch::Rails::Reporter
- Defined in:
- lib/dispatch/rails/reporter.rb
Overview
The capture entry point shared by the middleware and the error subscriber. Resolves the affected user, builds the event, applies client-side sampling and the before_send hook, and hands it to the transport. Never raises.
Constant Summary collapse
- CAPTURED_IVAR =
:@__dispatch_captured
Class Method Summary collapse
- .already_captured?(exception) ⇒ Boolean
- .capture(exception, handled:, env: nil, context: {}, level: "error") ⇒ Object
-
.mark_captured(exception) ⇒ Object
Mark the exception object so the same instance reported again (e.g. by the Rails executor after our middleware already handled it) isn’t double-sent.
-
.merged_tags(config, env, context) ⇒ Object
Tags sent with the event: the host app’s explicit context merged over whatever the config.context lambda resolves from the controller (an API-only app’s seam for X-API-Key user, X-Player-ID, etc.).
- .resolve_context(config, env) ⇒ Object
-
.resolve_user(config, env, context) ⇒ Object
Reuse the SAME config.user lambda the widget uses.
- .sampled_out?(config) ⇒ Boolean
Class Method Details
.already_captured?(exception) ⇒ Boolean
42 43 44 45 46 |
# File 'lib/dispatch/rails/reporter.rb', line 42 def already_captured?(exception) exception.instance_variable_defined?(CAPTURED_IVAR) rescue StandardError false end |
.capture(exception, handled:, env: nil, context: {}, level: "error") ⇒ Object
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/dispatch/rails/reporter.rb', line 13 def capture(exception, handled:, env: nil, context: {}, level: "error") config = Dispatch::Rails.configuration return unless config.error_tracking_enabled? return unless config.environment_enabled? return if already_captured?(exception) return if sampled_out?(config) mark_captured(exception) user = resolve_user(config, env, context) = (config, env, context) event = EventBuilder.call(exception, handled: handled, env: env, user: user, tags: , level: level) event = config.before_send.call(event) if config.before_send.respond_to?(:call) return if event.nil? Transport.instance.deliver(event) rescue StandardError => e warn "[dispatch-rails] capture failed: #{e.class}: #{e.}" nil end |
.mark_captured(exception) ⇒ Object
Mark the exception object so the same instance reported again (e.g. by the Rails executor after our middleware already handled it) isn’t double-sent.
36 37 38 39 40 |
# File 'lib/dispatch/rails/reporter.rb', line 36 def mark_captured(exception) exception.instance_variable_set(CAPTURED_IVAR, true) rescue StandardError nil end |
.merged_tags(config, env, context) ⇒ Object
60 61 62 63 64 65 |
# File 'lib/dispatch/rails/reporter.rb', line 60 def (config, env, context) base = resolve_context(config, env) base.merge(context[:tags] || {}) rescue StandardError context[:tags] || {} end |
.resolve_context(config, env) ⇒ Object
67 68 69 70 71 72 73 74 75 |
# File 'lib/dispatch/rails/reporter.rb', line 67 def resolve_context(config, env) return {} unless config.context.respond_to?(:call) controller = env && env["action_controller.instance"] result = config.context.call(controller) result.is_a?(Hash) ? result : {} rescue StandardError {} end |
.resolve_user(config, env, context) ⇒ Object
Reuse the SAME config.user lambda the widget uses. In a request we have the controller instance in the Rack env, so the lambda’s ‘ctx.current_user` works exactly as configured.
80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/dispatch/rails/reporter.rb', line 80 def resolve_user(config, env, context) return context[:user] if context[:user] return nil unless env && config.user.respond_to?(:call) controller = env["action_controller.instance"] return nil unless controller config.user.call(controller) rescue StandardError nil end |
.sampled_out?(config) ⇒ Boolean
48 49 50 51 52 53 54 |
# File 'lib/dispatch/rails/reporter.rb', line 48 def sampled_out?(config) rate = config.error_sample_rate.to_f return false if rate >= 1.0 return true if rate <= 0.0 rand > rate end |