inOperation<T> method

Future<T> inOperation<T>(
  1. String operationName,
  2. Future<T> fn()
)

Wraps an async operation with trace lifecycle and timing.

Starts a trace, executes fn, ends the trace, and records timing. On error, attaches error attributes to the trace and rethrows.

Implementation

Future<T> inOperation<T>(
  String operationName,
  Future<T> Function() fn,
) async {
  Trace? trace;
  try {
    trace = startTrace(operationName);
  } on Object catch (error, stack) {
    _diagnose(error, stack, 'startTrace');
  }
  final stopwatch = Stopwatch()..start();
  try {
    return await fn();
  } on Object catch (error, stack) {
    await safely(
      'recordOperationError',
      () => recordEvent(
        name: '$operationName.error',
        severity: TelemetrySeverity.error,
        message: 'The instrumented operation failed',
        context: {'errorType': error.runtimeType.toString()},
      ),
    );
    Error.throwWithStackTrace(error, stack);
  } finally {
    await safely(
      'recordTiming',
      () => recordTiming(
        name: '$operationName.duration',
        duration: stopwatch.elapsed,
      ),
    );
    final active = trace;
    if (active != null) {
      await safely('endTrace', () => endTrace(traceId: active.traceId));
    }
  }
}