Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: catch top level exception when preemptively creating streams #1584

Merged
merged 4 commits into from
Sep 21, 2023

Conversation

fryorcraken
Copy link
Collaborator

Resolves #1569

@fryorcraken
Copy link
Collaborator Author

@fbarbu15 @weboko

The test I added reproduces #1569 because of the following log line:
(node:347036) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 12)

and I can confirm the fix does remove this top level exception.

However, I tried in several manner to catch the exception in the test so that the test could fail when the exception is raised but to no avail. Do you have any suggestion?

@github-actions
Copy link

github-actions bot commented Sep 20, 2023

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
Waku core 28.82 KB (0%) 577 ms (0%) 478 ms (+54.44% 🔺) 1.1 s
Waku Simple Light Node 310.26 KB (+0.01% 🔺) 6.3 s (+0.01% 🔺) 1.6 s (+17.03% 🔺) 7.8 s
ECIES encryption 28.68 KB (0%) 574 ms (0%) 445 ms (-3.29% 🔽) 1.1 s
Symmetric encryption 28.68 KB (0%) 574 ms (0%) 395 ms (-8.16% 🔽) 968 ms
DNS discovery 118.59 KB (0%) 2.4 s (0%) 974 ms (+62.89% 🔺) 3.4 s
Privacy preserving protocols 122.63 KB (0%) 2.5 s (0%) 824 ms (+15.06% 🔺) 3.3 s
Light protocols 29.42 KB (+0.09% 🔺) 589 ms (+0.09% 🔺) 381 ms (-0.71% 🔽) 969 ms
History retrieval protocols 28.41 KB (+0.09% 🔺) 569 ms (+0.09% 🔺) 255 ms (+10.95% 🔺) 823 ms
Deterministic Message Hashing 5.64 KB (0%) 113 ms (0%) 79 ms (-37.82% 🔽) 192 ms

@fbarbu15
Copy link
Collaborator

@fbarbu15 @weboko

The test I added reproduces #1569 because of the following log line: (node:347036) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 12)

and I can confirm the fix does remove this top level exception.

However, I tried in several manner to catch the exception in the test so that the test could fail when the exception is raised but to no avail. Do you have any suggestion?

Tried multiple ways to catch the promise rejection but was only able to do it by checking the stderr. Might be another way but I'm no js expert.
Here's the code that worked for me

  it.only("Does not throw an exception when node disconnects", async function () {
     this.timeout(20_000);
     this.retries(0);

     const interceptedOutput: string[] = [];

     // Intercept and capture standard error
     const originalWrite = process.stderr.write.bind(process.stderr);

     (process.stderr.write as any) = (
       chunk: any,
       encoding?: any,
       callback?: any
     ): boolean => {
       interceptedOutput.push(chunk.toString());
       originalWrite(chunk, encoding, callback);
       return true;
     };

     nwaku = new NimGoNode(makeLogFileName(this));
     await nwaku.start({
       filter: true,
       store: true,
       lightpush: true
     });
     const multiAddrWithId = await nwaku.getMultiaddrWithId();

     waku = await createLightNode({
       staticNoiseKey: NOISE_KEY_1
     });
     await waku.start();
     await waku.dial(multiAddrWithId);
     await nwaku.stop();
     await waku.lightPush?.send(TestEncoder, {
       payload: utf8ToBytes("hello world")
     });
     await delay(1000);

     // Stop intercepting the sderr
     process.stderr.write = originalWrite;

     // Check if the desired output line is in the intercepted output
     if (
       interceptedOutput.some((line) =>
         line.includes("PromiseRejectionHandledWarning")
       )
     ) {
       throw new Error(
         "Detected PromiseRejectionHandledWarning in the output"
       );
     }
   });

@fryorcraken fryorcraken force-pushed the fix/lightpush-error-1569 branch from e0d6eb6 to 5838338 Compare September 21, 2023 01:53
@fryorcraken fryorcraken marked this pull request as ready for review September 21, 2023 01:56
@fryorcraken fryorcraken requested a review from a team as a code owner September 21, 2023 01:56
@fryorcraken
Copy link
Collaborator Author

fryorcraken commented Sep 21, 2023

I was able to detect the top level promise rejection and make the test fail based on it with:

      process.on("unhandledRejection", (e) =>
        expect.fail("unhandledRejection", e)
      );
      process.on("uncaughtException", (e) =>
        expect.fail("uncaughtException", e)
      );

@fbarbu15 it may be worth checking if we could have this piece of code present on all tests to ensure that Waku does not throw any uncaught exception or unhandled rejection.

@fryorcraken fryorcraken force-pushed the fix/lightpush-error-1569 branch from ab1a5bb to 8cbd4c1 Compare September 21, 2023 02:39
@fryorcraken fryorcraken merged commit c8def0c into master Sep 21, 2023
@fryorcraken fryorcraken deleted the fix/lightpush-error-1569 branch September 21, 2023 08:40
@weboko
Copy link
Collaborator

weboko commented Sep 21, 2023

Another way to catch promise rejection that is not popping out and is somewhere deep in the code - I think fake promise can be used (if I properly understood the problem). It depends on the testing stack and I am not sure how to handle it in mocha/chai.

Can research though

@danisharora099
Copy link
Collaborator

thanks!

@fbarbu15
Copy link
Collaborator

fbarbu15 commented Sep 21, 2023

I was able to detect the top level promise rejection and make the test fail based on it with:

      process.on("unhandledRejection", (e) =>
        expect.fail("unhandledRejection", e)
      );
      process.on("uncaughtException", (e) =>
        expect.fail("uncaughtException", e)
      );

@fbarbu15 it may be worth checking if we could have this piece of code present on all tests to ensure that Waku does not throw any uncaught exception or unhandled rejection.

I had a look at this and unfortunately this is making mocha exit with code 7 and stop execution of other tests. Also no test report is shown. I don't think this is what we want.
If we could fix this, then we could add it as a global beforeEach hook and run it for all tests. But I couldn't fix it, it either makes mocha exit or doesn't fail the test at all...

/home/fbarbu15/WORK_DIR/js-waku/node_modules/chai/lib/chai/interface/expect.js:41
    throw new chai.AssertionError(message, {
    ^
AssertionError: expect.fail()
    at process.<anonymous> (file:///home/fbarbu15/WORK_DIR/js-waku/packages/tests/tests/waku.node.spec.ts:77:16)
    at process.emit (node:events:526:35)
    at process.emit (node:domain:489:12)
    at process.emit.sharedData.processEmitHook.installedValue [as emit] (/home/fbarbu15/WORK_DIR/js-waku/node_modules/@cspotcode/source-map-support/source-map-support.js:745:40)
    at process._fatalException (node:internal/process/execution:149:25) {
  showDiff: false,
  actual: 'uncaughtException',
  expected: AssertionError: expect.fail()
      at process.<anonymous> (file:///home/fbarbu15/WORK_DIR/js-waku/packages/tests/tests/waku.node.spec.ts:74:16)
      at process.emit (node:events:514:28)
      at process.emit (node:domain:489:12)
      at process.emit.sharedData.processEmitHook.installedValue [as emit] (/home/fbarbu15/WORK_DIR/js-waku/node_modules/@cspotcode/source-map-support/source-map-support.js:745:40)
      at process.Runner.unhandled (/home/fbarbu15/WORK_DIR/js-waku/node_modules/mocha/lib/runner.js:192:19)
      at process.emit (node:events:526:35)
      at process.emit (node:domain:489:12)
      at process.emit.sharedData.processEmitHook.installedValue [as emit] (/home/fbarbu15/WORK_DIR/js-waku/node_modules/@cspotcode/source-map-support/source-map-support.js:745:40)
      at emit (node:internal/process/promises:149:20)
      at processPromiseRejections (node:internal/process/promises:283:27)
      at processTicksAndRejections (node:internal/process/task_queues:96:32) {
    showDiff: false,
    actual: 'unhandledRejection',
    expected: Error: Failed to get a connection to the peer
        at StreamManager.newStream (file:///home/fbarbu15/WORK_DIR/js-waku/packages/core/src/lib/stream_manager.ts:52:13)
        at StreamManager.prepareNewStream (file:///home/fbarbu15/WORK_DIR/js-waku/packages/core/src/lib/stream_manager.ts:58:32)
        at StreamManager.handlePeerUpdateStreamPool (file:///home/fbarbu15/WORK_DIR/js-waku/packages/core/src/lib/stream_manager.ts:66:12)
        at EventEmitter.[nodejs.internal.kHybridDispatch] (node:internal/event_target:741:20)
        at EventEmitter.dispatchEvent (node:internal/event_target:683:26)
        at EventEmitter.dispatchEvent (file:///home/fbarbu15/WORK_DIR/js-waku/node_modules/@libp2p/interface/src/events.ts:63:26)
        at EventEmitter.Libp2pNode.events.dispatchEvent (file:///home/fbarbu15/WORK_DIR/js-waku/node_modules/libp2p/src/libp2p.ts:65:30)
        at EventEmitter.safeDispatchEvent (file:///home/fbarbu15/WORK_DIR/js-waku/node_modules/@libp2p/interface/src/events.ts:78:17)
        at PersistentPeerStore.#emitIfUpdated (file:///home/fbarbu15/WORK_DIR/js-waku/node_modules/@libp2p/peer-store/src/index.ts:212:19)
        at PersistentPeerStore.patch (file:///home/fbarbu15/WORK_DIR/js-waku/node_modules/@libp2p/peer-store/src/index.ts:137:26)
        at processTicksAndRejections (node:internal/process/task_queues:95:5)
        at async file:///home/fbarbu15/WORK_DIR/js-waku/node_modules/libp2p/src/connection-manager/dial-queue.ts:241:13
        at async DefaultConnectionManager.openConnection (file:///home/fbarbu15/WORK_DIR/js-waku/node_modules/libp2p/src/connection-manager/index.ts:516:24)
        at async queue.add.peerId (file:///home/fbarbu15/WORK_DIR/js-waku/node_modules/libp2p/src/connection-manager/auto-dial.ts:266:9)
        at async file:///home/fbarbu15/WORK_DIR/js-waku/node_modules/p-queue/dist/index.js:118:36,
    operator: undefined,
    uncaught: true
  },
  operator: undefined
}

Node.js v18.17.1
Mocha tests exited with code 7
npm ERR! Lifecycle script `test:node` failed with error: 
npm ERR! Error: command failed 
npm ERR!   in workspace: @waku/[email protected] 
npm ERR!   at location: /home/fbarbu15/WORK_DIR/js-waku/packages/tests 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unhandled rejection when calling lightPush send
4 participants