LCOV - code coverage report
Current view: top level - lib/src/trace - span_exception_options.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 9 9
Test Date: 2026-07-11 13:35:19 Functions: - 0 0

            Line data    Source code
       1              : // Copyright The OpenTelemetry Authors
       2              : // SPDX-License-Identifier: Apache-2.0
       3              : 
       4              : /// Callback that transforms a raw exception into sanitized span data.
       5              : ///
       6              : /// Used by [SpanExceptionOptions.exceptionSanitizer] to control exactly what
       7              : /// exception information is recorded on a span, for example to strip PII,
       8              : /// tokens, request URLs, or user IDs from an error message before it is
       9              : /// recorded.
      10              : typedef ExceptionSanitizer = SanitizedSpanException Function(
      11              :   Object error,
      12              :   StackTrace stackTrace,
      13              : );
      14              : 
      15              : /// Controls how exceptions thrown from the function passed to
      16              : /// [Tracer.withSpan] / [Tracer.withSpanAsync] (and the convenience methods
      17              : /// that route through them) are recorded.
      18              : ///
      19              : /// Can be configured globally via `OTel.initialize(spanExceptionOptions: ...)`
      20              : /// (or per [TracerProvider] via [TracerProvider.spanExceptionOptions]) and
      21              : /// overridden per call via the `exceptionOptions` parameter of the withSpan
      22              : /// family. Per-call options are merged field-by-field over the global
      23              : /// configuration (see [mergeWith]), so overriding a single flag preserves the
      24              : /// globally configured sanitizer.
      25              : ///
      26              : /// The defaults preserve the library's historical behavior: a thrown
      27              : /// exception is recorded on the span and the span status is set to
      28              : /// [SpanStatusCode.Error]. The original exception is always rethrown
      29              : /// regardless of these options.
      30              : ///
      31              : /// Use this to opt out of automatic recording or status updates, or to
      32              : /// sanitize exception details via [exceptionSanitizer].
      33              : ///
      34              : /// Example:
      35              : /// ```dart
      36              : /// await tracer.withSpanAsync(
      37              : ///   span,
      38              : ///   () async => await doWork(),
      39              : ///   exceptionOptions: SpanExceptionOptions(
      40              : ///     exceptionSanitizer: (error, stackTrace) {
      41              : ///       return SanitizedSpanException(
      42              : ///         type: error.runtimeType.toString(),
      43              : ///         message: redact(error.toString()),
      44              : ///         stackTrace: sanitizeStackTrace(stackTrace),
      45              : ///         statusDescription: 'sanitized exception',
      46              : ///       );
      47              : ///     },
      48              : ///   ),
      49              : /// );
      50              : /// ```
      51              : class SpanExceptionOptions {
      52              :   /// Creates span exception options.
      53              :   ///
      54              :   /// Omitted parameters inherit from global configuration when these options
      55              :   /// are used as a per-call override (see [mergeWith]). Without global
      56              :   /// configuration, omitted parameters default to the SDK's standard
      57              :   /// behavior:
      58              :   /// - [recordException]: `true` — auto-record exceptions on the span
      59              :   /// - [setStatusOnException]: `true` — auto-set span status to error
      60              :   /// - [exceptionSanitizer]: `null` — record the raw exception as-is
      61          141 :   const SpanExceptionOptions({
      62              :     bool? recordException,
      63              :     bool? setStatusOnException,
      64              :     this.exceptionSanitizer,
      65              :   })  : _recordException = recordException,
      66              :         _setStatusOnException = setStatusOnException;
      67              : 
      68              :   /// The SDK default span exception behavior: record the exception and set
      69              :   /// the span status to error.
      70              :   static const SpanExceptionOptions defaults = SpanExceptionOptions(
      71              :     recordException: true,
      72              :     setStatusOnException: true,
      73              :   );
      74              : 
      75              :   final bool? _recordException;
      76              :   final bool? _setStatusOnException;
      77              : 
      78              :   /// Whether the SDK should automatically record the exception on the span.
      79              :   ///
      80              :   /// When `true` (default), the SDK records an `exception` event on the span.
      81              :   /// When `false`, the SDK skips automatic exception recording.
      82           10 :   bool get recordException => _recordException ?? true;
      83              : 
      84              :   /// Whether the SDK should automatically set the span status to
      85              :   /// [SpanStatusCode.Error] when the wrapped function throws.
      86              :   ///
      87              :   /// When `true` (the default) the status is set; when `false` it is left
      88              :   /// untouched.
      89           10 :   bool get setStatusOnException => _setStatusOnException ?? true;
      90              : 
      91              :   /// Optional callback to sanitize exception data before it is recorded.
      92              :   ///
      93              :   /// When provided, the SDK uses the returned [SanitizedSpanException] to
      94              :   /// record the exception instead of the raw error object — the original
      95              :   /// exception's type, message, and stack trace are never recorded, so
      96              :   /// unsanitized data cannot leak. This is useful for removing PII or other
      97              :   /// sensitive data from error messages.
      98              :   ///
      99              :   /// The sanitizer is only invoked when [recordException] or
     100              :   /// [setStatusOnException] is `true`. If the sanitizer itself throws, the
     101              :   /// original exception is not recorded and the span is marked with
     102              :   /// [SpanStatusCode.Error] using a generic description.
     103              :   final ExceptionSanitizer? exceptionSanitizer;
     104              : 
     105              :   /// Returns a new options object with [overrides] applied field-by-field.
     106              :   ///
     107              :   /// This allows a per-call override like
     108              :   /// `SpanExceptionOptions(recordException: false)` to keep a globally
     109              :   /// configured [exceptionSanitizer] while changing only one flag.
     110              :   ///
     111              :   /// Note: passing `exceptionSanitizer: null` in [overrides] is
     112              :   /// indistinguishable from not setting it — to intentionally clear a global
     113              :   /// sanitizer, use separate configuration.
     114           10 :   SpanExceptionOptions mergeWith(SpanExceptionOptions? overrides) {
     115              :     if (overrides == null) {
     116              :       return this;
     117              :     }
     118            1 :     return SpanExceptionOptions(
     119            2 :       recordException: overrides._recordException ?? _recordException,
     120              :       setStatusOnException:
     121            2 :           overrides._setStatusOnException ?? _setStatusOnException,
     122            2 :       exceptionSanitizer: overrides.exceptionSanitizer ?? exceptionSanitizer,
     123              :     );
     124              :   }
     125              : }
     126              : 
     127              : /// Sanitized exception data to record on a span.
     128              : ///
     129              : /// Returned by an [ExceptionSanitizer] to control exactly what gets recorded
     130              : /// as exception attributes on the span. The fields map directly to the
     131              : /// OpenTelemetry exception semantic conventions:
     132              : ///
     133              : /// - [type] -> `exception.type`
     134              : /// - [message] -> `exception.message`
     135              : /// - [stackTrace] -> `exception.stacktrace` (omitted when null)
     136              : class SanitizedSpanException {
     137              :   /// Creates a sanitized span exception.
     138            1 :   const SanitizedSpanException({
     139              :     required this.type,
     140              :     required this.message,
     141              :     this.stackTrace,
     142              :     this.statusDescription,
     143              :   });
     144              : 
     145              :   /// The exception type, recorded as the `exception.type` attribute.
     146              :   final String type;
     147              : 
     148              :   /// The sanitized error message, recorded as the `exception.message`
     149              :   /// attribute.
     150              :   final String message;
     151              : 
     152              :   /// Optional sanitized stack trace, recorded as the `exception.stacktrace`
     153              :   /// attribute. When `null`, no stack trace is recorded. The original
     154              :   /// (unsanitized) stack trace is never recorded when a sanitizer is used.
     155              :   final StackTrace? stackTrace;
     156              : 
     157              :   /// Optional status description used when setting the span status to
     158              :   /// [SpanStatusCode.Error]. Falls back to [message] when not provided.
     159              :   final String? statusDescription;
     160              : }
        

Generated by: LCOV version 2.0-1