amplitude / Amplitude-TypeScript

TypeScript Amplitude Analytics SDK
https://amplitude.github.io/Amplitude-TypeScript/
MIT License
129 stars 36 forks source link

track().promise and flush().promise never resolves #737

Closed oluckyman closed 2 months ago

oluckyman commented 5 months ago

Expected Behavior

I expect await track|flush().promise to resolve

Current Behavior

It awaits forever.

Possible Solution

I nailed down the issue is in transports/http:

          if (res.complete && responsePayload.length > 0) {
            try {
              // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
              var parsedResponsePayload = JSON.parse(responsePayload);
              var result = _this.buildResponse(parsedResponsePayload);
              console.log("RESOLVING RESULT!", result);
              resolve(result);
              return;
            } catch (_a) {
              resolve(null);
            }
          }
        });

This code never runs because res.complete is false, even though the server returns the correct result and registers the event:

{"code":200,"server_upload_time":1714999800311,"payload_size_bytes":274,"events_ingested":1}

Steps to Reproduce

import { flush, init, track, Types } from '@amplitude/analytics-node'
const client = init('my-key')
const logEvent: async () => {
    track('command', { command: 'bla bla' }, {
      user_id: userId,
    }).promise.then((res) => {
      // this func never runs
      return res
    })
    const f = flush()
    console.log(f.promise) // shows Promise { <pending> }
    console.log('now lets wait')
    const res = await f.promise
    console.log('got it', res) // never arrives to this line
}

Environment

sosafe-ugonna-ofoegbu commented 4 months ago

Currently having similar issue with identify().promise using package analytics-browser. It never resolves. Probably something related to changes made here https://github.com/amplitude/Amplitude-TypeScript/blob/405e60167a24f7e4dd66c379efe74f719d2e6b1a/packages/analytics-browser/src/utils/snippet-helper.ts#L15

Mercy811 commented 3 months ago

Hi @oluckyman,

You are missing await when track. I've changed https://github.com/amplitude/Amplitude-TypeScript/blob/1379195677af0120a09cdf632c3bae36baa4fd1c/examples/node/nest-app/src/app.controller.ts#L21 with the following and tested that it should work as expected

@Get('track')
  async track(): Promise<string> {
    await amplitude.track(
      'nest-app example event',
      { property1: '1' },
      { user_id: 'test_user' },
    ).promise.then(() => {
      console.log('Event sent successfully');
    }).catch((error) => {
      console.error('Error sending event:', error);
    });

    // Flushing the events
    const f = amplitude.flush();
    console.log(f.promise); // shows Promise { <pending> }
    console.log('now lets wait');

    const res = await f.promise;
    console.log('got it', res); // should log the flush result

    return 'Triggered, check console output...';
  }

Output:

Amplitude Logger [Log]: Event tracked successfully
Amplitude Logger [Debug]: {
  "type": "invoke public method",
  "name": "track",
  "args": [
    "nest-app example event",
    {
      "property1": "1"
    },
    {
      "user_id": "test_user"
    }
  ],
  "stacktrace": [
    "at AppController.track (/Users/xinyi.ye/Documents/GitHub/Amplitude-TypeScript/examples/node/nest-app/src/app.controller.ts:23:21)",
    "at /Users/xinyi.ye/Documents/GitHub/Amplitude-TypeScript/examples/node/nest-app/node_modules/@nestjs/core/router/router-execution-context.js:38:29",
    "at InterceptorsConsumer.intercept (/Users/xinyi.ye/Documents/GitHub/Amplitude-TypeScript/examples/node/nest-app/node_modules/@nestjs/core/interceptors/interceptors-consumer.js:11:20)",
    "at /Users/xinyi.ye/Documents/GitHub/Amplitude-TypeScript/examples/node/nest-app/node_modules/@nestjs/core/router/router-execution-context.js:46:60",
    "at /Users/xinyi.ye/Documents/GitHub/Amplitude-TypeScript/examples/node/nest-app/node_modules/@nestjs/core/router/router-proxy.js:9:23",
    "at Layer.handle [as handle_request] (/Users/xinyi.ye/Documents/GitHub/Amplitude-TypeScript/examples/node/nest-app/node_modules/express/lib/router/layer.js:95:5)",
    "at next (/Users/xinyi.ye/Documents/GitHub/Amplitude-TypeScript/examples/node/nest-app/node_modules/express/lib/router/route.js:144:13)",
    "at Route.dispatch (/Users/xinyi.ye/Documents/GitHub/Amplitude-TypeScript/examples/node/nest-app/node_modules/express/lib/router/route.js:114:3)"
  ],
  "time": {
    "start": "2024-06-24T21:09:37.187Z",
    "end": "2024-06-24T21:09:47.385Z"
  },
  "states": {
    "before": {
      "config.apiKey": "5b9a9510e261f9ead90865bbc5a7ad1d",
      "timeline.queue.length": 0
    },
    "after": {
      "config.apiKey": "5b9a9510e261f9ead90865bbc5a7ad1d",
      "timeline.queue.length": 0
    }
  }
}
Event sent successfully
Promise { <pending> }
now lets wait
Amplitude Logger [Debug]: {
  "type": "invoke public method",
  "name": "flush",
  "args": [],
  "stacktrace": [
    "at AppController.track (/Users/xinyi.ye/Documents/GitHub/Amplitude-TypeScript/examples/node/nest-app/src/app.controller.ts:34:25)",
    "at processTicksAndRejections (node:internal/process/task_queues:95:5)",
    "at /Users/xinyi.ye/Documents/GitHub/Amplitude-TypeScript/examples/node/nest-app/node_modules/@nestjs/core/router/router-execution-context.js:46:28",
    "at /Users/xinyi.ye/Documents/GitHub/Amplitude-TypeScript/examples/node/nest-app/node_modules/@nestjs/core/router/router-proxy.js:9:17"
  ],
  "time": {
    "start": "2024-06-24T21:09:47.387Z",
    "end": "2024-06-24T21:09:47.389Z"
  },
  "states": {
    "before": {
      "config.apiKey": "5b9a9510e261f9ead90865bbc5a7ad1d",
      "timeline.queue.length": 0
    },
    "after": {
      "config.apiKey": "5b9a9510e261f9ead90865bbc5a7ad1d",
      "timeline.queue.length": 0
    }
  }
}
got it undefined
Mercy811 commented 2 months ago

Close this issue as not hearing back.