nodejs / nodejs/node

coverage testing blocked by promise should report where that promise came from

Open
#59,940 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

test_runner
Dominant language
JavaScript
Stars
122k
Forks
37.3k
Avg merge
4d 2h
Merged PRs (30d)
283

Description

Version

24.8.0

Platform
macos sequioa
Subsystem

test runner

What steps will reproduce the bug?

create any dir and put a test.js file in it with content:

import test, { describe } from "node:test";
import assert from "node:assert/strict";

describe(`project testing`, async () => {
  test(`this'll hang`, async () => {
    const value = await new Promise((resolve) => {
      console.log(`looks like this'll never resolve()`);
    });
    assert.equal(value, true);
  });
});

Then run this with node --test "test.js"

Obviously this'll never finish, so hit ctrl-c, which triggers the final report and shows:

^C✖ test.js (1376.646ms)
ℹ tests 1
ℹ suites 0
ℹ pass 0
ℹ fail 0
ℹ cancelled 1
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 1379.56475

✖ failing tests:

test at test.js:1:1
✖ test.js (1376.646ms)
  'Promise resolution is still pending but the event loop has already resolved'

And, sure: that's true... but this message also isn't information, because it tells us nothing that lets us fix the problem.

Which promise is still pending? Which file, line, and column and the promise invocation be found on? Because Node knows where promise call sites are, and it should include that information in the error report.

How often does it reproduce? Is there a required condition?

This is how things work right now.

What is the expected behavior? Why is that the expected behavior?

The error should be:

test at test.js:6:18
✖ test.js (1598.681125ms)
  'Promise resolution is still pending but the event loop has already resolved'

explicitly showing the line things went wrong on.

And if there is a promise pending because of some dependency of a dependency, it should show that entire trace: if test.js is awaiting getInfo() imported from ./utils.js and that calls getNetworkDeviceNames() imported from ./utils/network.js and that has a promise that never resolves, then this error should let folks find that problem:

test at test.js:6:18
  at utils.js:20:14
  at utils/network.js:112:25
✖ test.js (1598.681125ms)
  'Promise resolution is still pending but the event loop has already resolved'

Or however traces should be made to look for this functionality. The important part is that it's informative so that we can fix bugs. After all, that's the whole point of using node --test =)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the behavior with the described test.js and node --test "test.js", then start from the test-runner handling of the pending-promise report. Trace how promise call sites and dependent async calls are represented, and define the output so it includes the originating locations and any relevant dependency trace.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
testing
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.