question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[I am sorry about this] Jest bug when using `MockScope.delay`

See original GitHub issue

Bug Description

I want to preface that using Jest was not my choice.

Reproducible By

import { MockAgent, setGlobalDispatcher, request } from 'undici'

const mockAgent = new MockAgent();
mockAgent.disableNetConnect();
setGlobalDispatcher(mockAgent);

const mockPool = mockAgent.get('http://localhost:3333');

mockPool.intercept({
	path: '/jest-bugs',
	method: 'GET'
}).reply(200, 'Hello').delay(100).times(2);

test('I wish this codebase used tap', async () => {
	const ac = new AbortController();
	setTimeout(() => ac.abort(), 5);
	const promise = request('http://localhost:3333/jest-bugs', {
		signal: ac.signal
	});

	await expect(promise).rejects.toThrowError('Request aborted');
}, 1000);

Expected Behavior

Logs & Screenshots

 PASS  __tests__/Jest.test.ts
  √ I wish this codebase used tap (16 ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |       0 |        0 |       0 |       0 | 
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.187 s, estimated 2 s
Ran all test suites matching /__tests__\\Jest.test.ts/i.
node:async_hooks:202
        ReflectApply(fn, thisArg, args);
        ^

TypeError: Function.prototype.apply was called on null, which is a object and not a function
    at RequestHandler.runInAsyncScope (node:async_hooks:202:9)
    at RequestHandler.onHeaders (\node_modules\undici\lib\api\api-request.js:91:10)
    at handleReply (\node_modules\undici\lib\mock\mock-utils.js:200:13)
    at Timeout._onTimeout (\node_modules\undici\lib\mock\mock-utils.js:189:7)
    at listOnTimeout (node:internal/timers:559:17)
    at processTimers (node:internal/timers:502:7)

Node.js v17.8.0

Environment

Windows 10 Nodejs v17.8.0

Additional context

Even though the test passes, the CI still exits with exit code 1 and the workflow fails 😢

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
KhafraDevcommented, Apr 15, 2022

Not that bad to debug really… much easier than I expected.

Somewhere an error occurs, triggering the onError callback; https://github.com/nodejs/undici/blob/f5d9a94e8771708a2d3654e412cb82404bf7cf4f/lib/api/api-request.js#L116 where err is

RequestAbortedError [AbortError]: Request aborted
          at abort (\undici\lib\api\abort-signal.js:12:18)
          at AbortSignal.self.<computed> (\undici\lib\api\abort-signal.js:32:5)
          at AbortSignal.[nodejs.internal.kHybridDispatch] (node:internal/event_target:643:20)
          at AbortSignal.dispatchEvent (node:internal/event_target:585:26)
          at abortSignal (node:internal/abort_controller:291:10)
          at AbortController.abort (node:internal/abort_controller:322:5)
          at Timeout._onTimeout (\undici\test\jest\jest.test.js:17:22)
          at listOnTimeout (node:internal/timers:559:17)
          at processTimers (node:internal/timers:502:7) {
        code: 'UND_ERR_ABORTED'
      }

      at RequestHandler.onError (lib/api/api-request.js:119:13)

The stack trace itself doesn’t mean much, it just shows that the request was successfully aborted (yay!).

Since callback exists, the statement runs, and sets the callback to null here; https://github.com/nodejs/undici/blob/f5d9a94e8771708a2d3654e412cb82404bf7cf4f/lib/api/api-request.js#L123

If the fix is just to add an if (callback !== null) { ... } then I am glad to make a PR, but I’m not really familiar with this section of the code and what [in]correct behavior looks like.

1reaction
mcollinacommented, Apr 9, 2022

My reading of this bug is that is a jest bug. It seems they are modifying the timers lists from the outside, causing this error in the async_hooks machinery.

I likely don’t have the time to debug this 😦.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Service mocked with Jest causes "The module factory of jest ...
This solution is based on the Note at the end of the error message I was getting. Note: This is a precaution to...
Read more >
How To Apologize For a Delay by Email or in Person - Indeed
Immediately follow your greeting with an apology for your delayed response. Use a straightforward phrase that acknowledges the tardiness. Here ...
Read more >
How to Say “Sorry” in Polish to Sound Like a (Polite) Native ...
This is the direct translation of “sorry”, and the single most common way to apologize in Polish. In fact, the word has two...
Read more >
Top Email Etiquette Tips When You Need To Say “Sorry For ...
While apologizing, especially at work, can sometimes be uncomfortable, it's the quickest way to move past a delayed email response and get back ......
Read more >
StackExchange.Redis.RedisTimeoutException - IssueHint
Intermittently I see following error in my logs StackExchange. ... [I am sorry about this] Jest bug when using `MockScope.delay`, 5, 2022-04-09, 2022-09-28 ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found