wrap()

in src/aws/AWSLambdaTriggerPlugin.ts [81:150]


  wrap(func: any) {
    return async (event: any, context: any, callback: any) => {
      const ts = performance.now() / 1000;

      let done = async (err: Error | null, res?: any) => {
        done = async (err: Error | null, res?: any) => res;

        if (err) span.error(err);

        this.stop(span, err, res);

        if (config.awsLambdaFlush >= 0) {
          if (ts - _lastTimestamp >= config.awsLambdaFlush) {
            await new Promise((resolve) => setTimeout(resolve, 0)); // child spans of this span may have finalization waiting in the event loop in which case we give them a chance to run so that the segment can be archived properly for flushing

            const p = agent.flush(); // flush all data before aws freezes the process on exit

            if (p) await p;
          }

          _lastTimestamp = performance.now() / 1000;
        }

        return res;
      };

      let cbdone = (err: Error | null, res?: any): any => {
        // for the weird AWS done function behaviors
        cbdone = (err: Error | null, res?: any) => ({ finally: () => undefined });

        return done(err, res);
      };

      ContextManager.clearAll(); // need this because AWS seems to chain sequential independent operations linearly instead of hierarchically

      const _done = context.done;
      const [span, _event] = this.start(event, context);

      try {
        event = _event;
        span.layer = SpanLayer.HTTP;

        if (context.invokedFunctionArn) span.tag(Tag.arn(context.invokedFunctionArn));

        context.done = (err: Error | null, res: any) => {
          cbdone(err, res).finally(() => _done(err, res));
        };
        context.succeed = (res: any) => {
          cbdone(null, res).finally(() => _done(null, res));
        };
        context.fail = (err: Error | null) => {
          cbdone(err).finally(() => _done(err));
        };

        let ret = func(event, context, (err: Error | null, res: any) => {
          cbdone(err, res).finally(() => callback(err, res));
        });

        if (typeof ret?.then === 'function')
          // generic Promise check
          ret = await ret;

        return await done(null, ret);
      } catch (e) {
        await done(e, null);

        throw e;
      }
    };
  }