{"version":3,"file":"SugaredTracer.js","sourceRoot":"","sources":["../../../../src/experimental/trace/SugaredTracer.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE/D,MAAM,kBAAkB,GAAG,CAAC,CAAQ,EAAE,IAAU,EAAE,EAAE;IAClD,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACxB,IAAI,CAAC,SAAS,CAAC;QACb,IAAI,EAAE,cAAc,CAAC,KAAK;KAC3B,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,IAAI,aAAa,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,OAAO,aAAa;IAGxB,YAAY,MAAc;QACxB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnE,CAAC;IA0CD,cAAc,CACZ,IAAY,EACZ,IAA4B,EAC5B,IAAkB,EAClB,IAAQ;QAER,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAE1D,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,IAAU,EAAE,EAAE,CAClE,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CACR,CAAC;IACrB,CAAC;IA4CD,QAAQ,CACN,IAAY,EACZ,IAA4B,EAC5B,IAAkB,EAClB,IAAQ;QAER,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAE1D,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;QACrD,OAAO,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAkB,CAAC;IACnD,CAAC;CACF;AAED;;;;;GAKG;AACH,SAAS,aAAa,CACpB,GAA2B,EAC3B,IAAkB,EAClB,IAAQ;IAER,IAAI,IAAoC,CAAC;IACzC,IAAI,GAAwB,CAAC;IAC7B,IAAI,EAAK,CAAC;IAEV,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE;QAClB,EAAE,GAAG,GAAQ,CAAC;KACf;SAAM,IAAI,CAAC,IAAI,EAAE;QAChB,IAAI,GAAG,GAAyB,CAAC;QACjC,EAAE,GAAG,IAAS,CAAC;KAChB;SAAM;QACL,IAAI,GAAG,GAAyB,CAAC;QACjC,GAAG,GAAG,IAAe,CAAC;QACtB,EAAE,GAAG,IAAS,CAAC;KAChB;IACD,IAAI,GAAG,IAAI,aAAJ,IAAI,cAAJ,IAAI,GAAI,EAAE,CAAC;IAClB,GAAG,GAAG,GAAG,aAAH,GAAG,cAAH,GAAG,GAAI,UAAU,CAAC,MAAM,EAAE,CAAC;IAEjC,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;GAKG;AACH,SAAS,QAAQ,CACf,IAAU,EACV,IAAwB,EACxB,EAAK;;IAEL,MAAM,WAAW,GAAG,MAAA,IAAI,CAAC,WAAW,mCAAI,kBAAkB,CAAC;IAC3D,MAAM,YAAY,GAAG,CAAC,CAAQ,EAAE,EAAE;QAChC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC,GAAG,EAAE,CAAC;QACX,MAAM,CAAC,CAAC;IACV,CAAC,CAAC;IAEF,IAAI;QACF,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAA2B,CAAC;QAC/C,2FAA2F;QAC3F,IAAI,OAAO,CAAA,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,IAAI,CAAA,KAAK,UAAU,EAAE;YACnC,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;gBACpB,IAAI,CAAC,GAAG,EAAE,CAAC;gBACX,OAAO,GAAG,CAAC;YACb,CAAC,EAAE,YAAY,CAAkB,CAAC;SACnC;QACD,IAAI,CAAC,GAAG,EAAE,CAAC;QACX,OAAO,GAAoB,CAAC;KAC7B;IAAC,OAAO,CAAC,EAAE;QACV,2EAA2E;QAC3E,MAAM,YAAY,CAAC,CAAC,CAAC,CAAC;KACvB;AACH,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type { SugaredSpanOptions } from './SugaredOptions';\nimport type { Context, Span, Tracer } from '../../';\nimport { context as contextApi, SpanStatusCode } from '../../';\n\nconst defaultOnException = (e: Error, span: Span) => {\n  span.recordException(e);\n  span.setStatus({\n    code: SpanStatusCode.ERROR,\n  });\n};\n\n/**\n * return a new SugaredTracer created from the supplied one\n * @param tracer\n */\nexport function wrapTracer(tracer: Tracer): SugaredTracer {\n  return new SugaredTracer(tracer);\n}\n\nexport class SugaredTracer implements Tracer {\n  private readonly _tracer: Tracer;\n\n  constructor(tracer: Tracer) {\n    this._tracer = tracer;\n    this.startSpan = tracer.startSpan.bind(this._tracer);\n    this.startActiveSpan = tracer.startActiveSpan.bind(this._tracer);\n  }\n\n  startActiveSpan: Tracer['startActiveSpan'];\n  startSpan: Tracer['startSpan'];\n\n  /**\n   * Starts a new {@link Span} and calls the given function passing it the\n   * created span as first argument.\n   * Additionally, the new span gets set in context and this context is activated\n   * for the duration of the function call.\n   * The span will be closed after the function has executed.\n   * If an exception occurs, it is recorded, the status is set to ERROR and the exception is rethrown.\n   *\n   * @param name The name of the span\n   * @param [options] SugaredSpanOptions used for span creation\n   * @param [context] Context to use to extract parent\n   * @param fn function called in the context of the span and receives the newly created span as an argument\n   * @returns return value of fn\n   * @example\n   *     const something = tracer.withActiveSpan('op', span => {\n   *      // do some work\n   *     });\n   * @example\n   *     const something = await tracer.withActiveSpan('op', span => {\n   *      // do some async work\n   *     });\n   */\n  withActiveSpan<F extends (span: Span) => ReturnType<F>>(\n    name: string,\n    fn: F\n  ): ReturnType<F>;\n  withActiveSpan<F extends (span: Span) => ReturnType<F>>(\n    name: string,\n    options: SugaredSpanOptions,\n    fn: F\n  ): ReturnType<F>;\n  withActiveSpan<F extends (span: Span) => ReturnType<F>>(\n    name: string,\n    options: SugaredSpanOptions,\n    context: Context,\n    fn: F\n  ): ReturnType<F>;\n  withActiveSpan<F extends (span: Span) => ReturnType<F>>(\n    name: string,\n    arg2: F | SugaredSpanOptions,\n    arg3?: F | Context,\n    arg4?: F\n  ): ReturnType<F> {\n    const { opts, ctx, fn } = massageParams(arg2, arg3, arg4);\n\n    return this._tracer.startActiveSpan(name, opts, ctx, (span: Span) =>\n      handleFn(span, opts, fn)\n    ) as ReturnType<F>;\n  }\n\n  /**\n   * Starts a new {@link Span} and ends it after execution of fn without setting it on context.\n   * The span will be closed after the function has executed.\n   * If an exception occurs, it is recorded, the status is et to ERROR and rethrown.\n   *\n   * This method does NOT modify the current Context.\n   *\n   * @param name The name of the span\n   * @param [options] SugaredSpanOptions used for span creation\n   * @param [context] Context to use to extract parent\n   * @param fn function called in the context of the span and receives the newly created span as an argument\n   * @returns Span The newly created span\n   * @example\n   *     const something = tracer.withSpan('op', span => {\n   *      // do some work\n   *     });\n   * @example\n   *     const something = await tracer.withSpan('op', span => {\n   *      // do some async work\n   *     });\n   */\n  withSpan<F extends (span: Span) => ReturnType<F>>(\n    name: string,\n    fn: F\n  ): ReturnType<F>;\n  withSpan<F extends (span: Span) => ReturnType<F>>(\n    name: string,\n    options: SugaredSpanOptions,\n    fn: F\n  ): ReturnType<F>;\n  withSpan<F extends (span: Span) => ReturnType<F>>(\n    name: string,\n    options: SugaredSpanOptions,\n    context: Context,\n    fn: F\n  ): ReturnType<F>;\n  withSpan<F extends (span: Span) => ReturnType<F>>(\n    name: string,\n    options: SugaredSpanOptions,\n    context: Context,\n    fn: F\n  ): ReturnType<F>;\n  withSpan<F extends (span: Span) => ReturnType<F>>(\n    name: string,\n    arg2: SugaredSpanOptions | F,\n    arg3?: Context | F,\n    arg4?: F\n  ): ReturnType<F> {\n    const { opts, ctx, fn } = massageParams(arg2, arg3, arg4);\n\n    const span = this._tracer.startSpan(name, opts, ctx);\n    return handleFn(span, opts, fn) as ReturnType<F>;\n  }\n}\n\n/**\n * Massages parameters of withSpan and withActiveSpan to allow signature overwrites\n * @param arg\n * @param arg2\n * @param arg3\n */\nfunction massageParams<F extends (span: Span) => ReturnType<F>>(\n  arg: F | SugaredSpanOptions,\n  arg2?: F | Context,\n  arg3?: F\n) {\n  let opts: SugaredSpanOptions | undefined;\n  let ctx: Context | undefined;\n  let fn: F;\n\n  if (!arg2 && !arg3) {\n    fn = arg as F;\n  } else if (!arg3) {\n    opts = arg as SugaredSpanOptions;\n    fn = arg2 as F;\n  } else {\n    opts = arg as SugaredSpanOptions;\n    ctx = arg2 as Context;\n    fn = arg3 as F;\n  }\n  opts = opts ?? {};\n  ctx = ctx ?? contextApi.active();\n\n  return { opts, ctx, fn };\n}\n\n/**\n * Executes fn, returns results and runs onException in the case of exception to allow overwriting of error handling\n * @param span\n * @param opts\n * @param fn\n */\nfunction handleFn<F extends (span: Span) => ReturnType<F>>(\n  span: Span,\n  opts: SugaredSpanOptions,\n  fn: F\n): ReturnType<F> {\n  const onException = opts.onException ?? defaultOnException;\n  const errorHandler = (e: Error) => {\n    onException(e, span);\n    span.end();\n    throw e;\n  };\n\n  try {\n    const ret = fn(span) as Promise<ReturnType<F>>;\n    // if fn is an async function, attach a recordException and spanEnd callback to the promise\n    if (typeof ret?.then === 'function') {\n      return ret.then(val => {\n        span.end();\n        return val;\n      }, errorHandler) as ReturnType<F>;\n    }\n    span.end();\n    return ret as ReturnType<F>;\n  } catch (e) {\n    // add throw to signal the compiler that this will throw in the inner scope\n    throw errorHandler(e);\n  }\n}\n"]}