Module: Foam::Otel::Errors
- Defined in:
- lib/foam/otel/errors.rb
Overview
One exception, one event (contract SPEC.md section 12): every capture path — the Rack middleware's unhandled-raise rescue, the railtie's process_action notification hook, the error-tracker bridge, and the public record_exception API — records through here, deduped per span by exception object identity.
The seen-set lives ON the span object (an instance variable), not in a thread-local: a request span can be recorded on one thread and finished on another (ActionController::Live streams the response body from a separate thread), so a thread-local would both miss the dedupe/recorded check across threads and leak entries for spans that never pass back through their owning thread. Span-carried state is GC'd with the span and travels with it across threads.
Constant Summary collapse
- IVAR =
:@__foam_otel_recorded
Class Method Summary collapse
-
.record_once(span, error) ⇒ Object
Records
erroronspan(exception event + status ERROR) unless this exact exception object was already recorded there. -
.recorded?(span) ⇒ Boolean
Whether any exception has been recorded on this span (so a later OK status never clobbers a thrown-then-mapped ERROR — SPEC section 6).
Class Method Details
.record_once(span, error) ⇒ Object
Records error on span (exception event + status ERROR) unless this
exact exception object was already recorded there. Never raises.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/foam/otel/errors.rb', line 25 def record_once(span, error) return false unless span.respond_to?(:context) && span.context.valid? return false unless span.respond_to?(:recording?) && span.recording? seen = span.instance_variable_get(IVAR) unless seen seen = [] span.instance_variable_set(IVAR, seen) end return false if seen.include?(error.object_id) seen << error.object_id span.record_exception(error) span.status = OpenTelemetry::Trace::Status.error(error..to_s) true rescue StandardError false end |
.recorded?(span) ⇒ Boolean
Whether any exception has been recorded on this span (so a later OK status never clobbers a thrown-then-mapped ERROR — SPEC section 6).
46 47 48 49 50 51 |
# File 'lib/foam/otel/errors.rb', line 46 def recorded?(span) seen = span.instance_variable_get(IVAR) !seen.nil? && !seen.empty? rescue StandardError false end |