jestjs / jest

Delightful JavaScript Testing.
https://jestjs.io
MIT License
44.04k stars 6.44k forks source link

Jest failing with "Call retries were exceeded", using --runInBand works-around issue #8769

Open martijnthe opened 5 years ago

martijnthe commented 5 years ago

🐛 Bug Report

I've got 2 test files. In the test, a WebAssembly object gets instantiated. This instantiation seems to stall for some reason when running the test in CI. Locally running jest passes the tests fine.

In CI they fail with this error:

  ● Test suite failed to run

    Call retries were exceeded

      at ChildProcessWorker.initialize (../node_modules/jest-worker/build/workers/ChildProcessWorker.js:193:21)

When -i is used however, they pass as well in CI.

Jest: 24.8.0 Node: 10.15.0 Local env: macOS, 10.14.6 (18G84)) CI env: CircleCI, Docker Linux 6a7bd3b63625 4.15.0-1035-aws #37-Ubuntu SMP Mon Mar 18 16:15:14 UTC 2019 x86_64 GNU/Linux

To Reproduce

I don't have a concise repro repo at this moment.

Expected behavior

I expect the tests to pass as well when not run in band.

Link to repl or repo (highly encouraged)

Don't have it at this moment.

Run npx envinfo --preset jest

Paste the results here:

CI:

npx: installed 1 in 1.719s

  System:
    OS: Linux 4.15 Debian GNU/Linux 9 (stretch) 9 (stretch)
    CPU: (36) x64 Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz
  Binaries:
    Node: 10.15.0 - ~/.nodenv/versions/10.15.0/bin/node
    Yarn: 1.17.3 - /usr/bin/yarn
    npm: 6.4.1 - ~/.nodenv/versions/10.15.0/bin/npm

Local:

Environment:
  OS:  macOS 10.14.6
  Node:  10.15.0
  Yarn:  1.17.3
  npm:  6.4.1
  Watchman:  Not Found
  Xcode:  Xcode 10.3 Build version 10G8
  Android Studio:  3.1 AI-173.4819257
riyazinteractive commented 3 years ago

For me, I have to uninstall watchman and reinstall using brew. After executing the below cmd the issue was resolved. Hope this helps.

npm r -g watchman brew install watchman

tomasbruckner commented 3 years ago

Same issue node 16.0, also ERR_UNHANDLED_REJECTION

hwebb commented 3 years ago

I get this error as well, I don't even know what jest-worker is, but I see it in package-lock.json. I don't know which module is implementing this, is there a way to just disable it completely?

scitech commented 3 years ago

For us this actually happened due to uncaught promise rejection. The error message was pretty far from actionable :D So there is apparently far more reasons for this error to occur than just OOM.

This was the case for us, too. I suspect if anyone else out there is seeing test suites fail to run with the "Call retries were exceeded" message after upgrading to Node 15 and above, you might want to hunt down and fix any unhanded promise rejections in your codebase.

I created a small reproducing repo in case it helps anyone on the Jest team: https://github.com/scitech/call-retries-repro

I think the issue here is, Jest will spawn some number of workers which will each attempt to fork a process. If a worker's process dies it forks another one, but after 3 tries it will stop running tests, and subsequent test suites will fail with the rather obscure error message "Call retries were exceeded". So it's not specifically related to unhandled promise rejections or memory issues (as in the OP) -- the failure could be due to a worker encountering 3 Node exceptions of any kind.

Given that unhandled promise rejections are pretty common in application code, I wonder if there isn't a more informative way to presenting this information to the Jest user so they can track down the issue. Forgive the unsolicited suggestions but here are some ideas:

  1. Changing the error message text. "Call retries exceeded" is pretty opaque, maybe to something like "Jest worker process exited 3 times due to Node process exceptions, exceeding retry limit."
  2. If a child process worker exceeds the retry limit, can it bail early, rather than run all the tests marking each as failed? It's harder to find the original source of the problem as is.
  3. Can the exit handler of the ChildProcessWorker collect the Node process exception messages and report them back out after exceeding the retry limit?
thelinuxlich commented 3 years ago

For me it happened with lazy imports...just repurposed them into normal imports and it worked.

mwerder commented 3 years ago

I think I had the same error:

Failed to construct transformer: { Error: Call retries were exceeded at ChildProcessWorker.initialize (/Users/developer/Documents/dev/docomondo/app/node_modules/jest-worker/build/workers/ChildProcessWorker.js:193:21) at ChildProcessWorker._onExit (/Users/developer/Documents/dev/docomondo/app/node_modules/jest-worker/build/workers/ChildProcessWorker.js:274:12) at ChildProcess.emit (events.js:198:13) at Process.ChildProcess._handle.onexit (internal/child_process.js:248:12) type: 'WorkerError' }

I updated node from v10.19.0 to v14.17.0 and it works now

mnmajd commented 3 years ago

I have the same issue , but locally it works fine the tests passes however in CI it give me this error too !

whatwewant commented 3 years ago

Solved with: jest -w 1, hope to help others.

https://github.com/zcorky/moment/issues/26

Sriram-Nithyanandam commented 3 years ago

I faced the same error when I was using node version 16.3. Changing the version from 16.3 to 12.6.3 resolved this issue.

chiragt commented 3 years ago

I think I had the same error:

Failed to construct transformer: { Error: Call retries were exceeded at ChildProcessWorker.initialize (/Users/developer/Documents/dev/docomondo/app/node_modules/jest-worker/build/workers/ChildProcessWorker.js:193:21) at ChildProcessWorker._onExit (/Users/developer/Documents/dev/docomondo/app/node_modules/jest-worker/build/workers/ChildProcessWorker.js:274:12) at ChildProcess.emit (events.js:198:13) at Process.ChildProcess._handle.onexit (internal/child_process.js:248:12) type: 'WorkerError' }

I updated node from v10.19.0 to v14.17.0 and it works now

This worked for me

jiaoqiqi commented 3 years ago

Meet the same issue when upgrade node from 12.13 to 16, any update on this? "jest": "^25.5.4", "react": "^16.14.0", "node": "16"

Test suite failed to run

    Call retries were exceeded

      at ChildProcessWorker.initialize (node_modules/jest-worker/build/workers/ChildProcessWorker.js:191:21)
      at ChildProcess.emit (node:events:394:28)
      at Process.ChildProcess._handle.onexit (node:internal/child_process:290:12)
wesyao commented 2 years ago

@jiaoqiqi I'm also still seeing this issue on node 16.9. However, I've been able to mitigate this by pinning node to 16.8.

Hopefully there is a longer term fix soon.

SevenOutman commented 2 years ago

Conclusion

If you are experiencing this issue on a CI environment, it's probably caused by a CPU limit that prevents Jest from creating as many child processes as it wants.

Try setting --maxWorkers option to appropriate value to tell Jest how many child processes it can possibly request.

Original comment

I'm experiencing this issue on GitLab CI on a k8s cluster after I set the CPU limit of the runner pod to 5 cores (while the cluster has 40 in total).

I guess the Node.js told jest-runner that the system has 40 cores so jest-runner requested for according number of child processes, then the CPU limit caused the child process request to fail.

Solved with setting --maxWorkers to lower than 5.

adrian-pc-code commented 2 years ago

@jiaoqiqi I'm also still seeing this issue on node 16.9. However, I've been able to mitigate this by pinning node to 16.8.

Hopefully there is a longer term fix soon.

I'm having this issue on 16.8.0 I have a feeling that the node version is a red herring and the problem is getting fixed after upgrades/downgrades because something else changes as a side effect.

jorenceT commented 2 years ago

For me the issue came when I used spyon on a api call. Initialy I was using spyOn(dataService, 'getData').and.returnValue({ paydown: 0, depAmount: null });

Then it worked when I changed the code to callfake

spyOn(dataService, 'getData').and.callFake(() => Promise.resolve({ paydown: 0, depAmount: null }));

mnmajd commented 2 years ago

Guys for me it was just the node version that i use in localhost is not the the same used in the pipeline to run tests !

azidouk commented 2 years ago

I am seeing a similar issue with node v16.10.0. In my case, however, I am running locally and --runInBand causes the test to throw:

node:internal/process/promises:246
          triggerUncaughtException(err, true /* fromPromise */);
          ^

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Error: For security reasons, `window.crypto` is required to run `auth0-spa-js`.".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

Reverting back to node 12.20.1 resolves the issue but it seems like more than just a node version problem.

stefdelec commented 2 years ago

Similir problem here! Not working on 14 and 16, but works on node 12.

jamesRaybould commented 2 years ago

I've run into this issue when updating a codebase from Node12 -> Node16 and in my digging I've found that in the bits that are now failing all seem to have the following in common when I run with a debugger attached.

[DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Which would indicate to me that the behaviour it was relying on, unhandled promise rejections continue, now cause a termination in Node, which Jest is detecting, running the test an additional 3 times before declaring it as dead and marks it as a test suite that has failed to execute.

What is interesting is that in Node12 those tests pass even when unhandled promise rejection is being fired as long as it's not actually impacting any of the bits that are being tested.

Would it be possible to bubble up those Unhandled promise rejection errors so it's easier for people to spot rather than having to spelunk using the debugger to work out what is wrong?

Jest 27.2.3 Node 12.18.2 - All tests work as expected Node 16.13.0 - Tests that contain an Unhandled promise rejection fail, even if it's not in the tests critical path

olikari87 commented 2 years ago

Having the same problem

jest: 26.6.3 node: 15.5.1

node:internal/process/promises:227
          triggerUncaughtException(err, true /* fromPromise */);

Call retries were exceeded

      at ChildProcessWorker.initialize (node_modules/jest-worker/build/workers/ChildProcessWorker.js:193:21)
leonheess commented 2 years ago

Same issue here

yoshicarroll commented 2 years ago

jamesRaybould's description matches the problem I have as well. Worked in node 14.17.16, fails in 16.13.0.

nvh95 commented 2 years ago

In my case we're missing an await before wairFor from @testing-library/react

- waitFor(() => {

+ await waitFor(() => {
      expect(screen.getByTestId('my-button')).toBeInTheDocument();

If we run with node 16, it does not complain at all. Node 14 yells Call retries were exceeded without any implicit error message and it's very difficult to spot the bug.

NeffIsBack commented 2 years ago

Same Problem here:

 FAIL  __tests__/homepage.test.tsx
  ● Test suite failed to run

    Jest worker encountered 4 child process exceptions, exceeding retry limit

      at ChildProcessWorker.initialize (node_modules/jest-worker/build/workers/ChildProcessWorker.js:185:21)

Node version: v16.13.0

Does anyone got a fix?

jamesRaybould commented 2 years ago

From my understanding of the problem I think the best fix for this is probably to fix the problem at source, in my case it's a combination of us not mocking out dependencies properly and a couple of places where we don't actually handle the promise rejection (at all). So fixing those will get us to a place where it all works as expected.

I'm not sure that there is a fix that can go in Jest other than to maybe better highlight where the unhandledPromiseRejection is being thrown.

encreinformatique commented 2 years ago

I had the same problem with a VueJS app, with nodejs v16.13.0 and jest 25.5.4 so a bit older version of Jest.

node:internal/process/promises:246
          triggerUncaughtException(err, true /* fromPromise */);
          ^

and Call retries were exceeded

"Fixed" it with the following changed. I prefer the former syntax than the latter.

    components: {
      VueApexCharts: () => import('vue-apexcharts')
    }

to

    import VueApexCharts from 'vue-apexcharts'
...
    components: {
      VueApexCharts
    }
mauryakrishna commented 2 years ago

In my case we're missing an await before wairFor from @testing-library/react

- waitFor(() => {

+ await waitFor(() => {
      expect(screen.getByTestId('my-button')).toBeInTheDocument();

If we run with node 16, it does not complain at all. Node 14 yells Call retries were exceeded without any implicit error message and it's very difficult to spot the bug.

Do not know why but this worked like charm.

regischow commented 2 years ago

For those having issues running on node 16, I found this link helpful, https://stackoverflow.com/questions/68368577/react-tests-unhandledpromiserejection

Essentially you need to ensure that any custom async functions being called from your tests need to implement a try/catch.

steevsachs commented 2 years ago

We ran into this issue when upgrading from Node 14 to Node 16. It appears that Node 15 introduced a breaking change to promise rejection handling, as @jamesRaybould indicated earlier. I found https://developer.ibm.com/blogs/nodejs-15-release-blog/ to be a helpful writeup of the change.

We saw the errors disappear after passing the --unhandled-rejections=warn flag to node when running tests, which likely confirms this diagnosis.

Passing that flag may work as a short term workaround.

arivestNexapp commented 2 years ago

My problem was that a testing-library test was longer than the 5 seconds timeout of a test. There are multiples waitFor in it as it represent an E2E test.

In order to fix it, I simply needed to up the timeout of the test to an higher value:

it('should do a mega long process`, () => {
  renderComponent();

  // all the process

  expect(true).toBeTruthy()
}, 60 * 1000) // one minute to be sure it does not timeout again

Hope it helps some of you!

nvh95 commented 2 years ago

My problem was that a testing-library test was longer than the 5 seconds timeout of a test. There are multiples waitFor in it as it represent an E2E test.

@arivestNexapp Another option is you can configure it globally, so you don't have to manually increase timeout for each test.

import { configure } from '@testing-library/dom';

configure({
  asyncUtilTimeout: 2500,
});

Reference: https://testing-library.com/docs/dom-testing-library/api-configuration#asyncutiltimeout

dicutaia commented 2 years ago

In my case we're missing an await before wairFor from @testing-library/react

- waitFor(() => {

+ await waitFor(() => {
      expect(screen.getByTestId('my-button')).toBeInTheDocument();

If we run with node 16, it does not complain at all. Node 14 yells Call retries were exceeded without any implicit error message and it's very difficult to spot the bug.

Do not know why but this worked like charm.

In my case, I was not awaiting a findByText. Switching to getByText fixed the issue for me.

nlasso-longevo commented 2 years ago

Hi, for me this error was related to M1 processor. Run tests on a terminal with rosetta enabled and got it working.

mohammedabdulai commented 2 years ago

For those having issues running on node 16, I found this link helpful, https://stackoverflow.com/questions/68368577/react-tests-unhandledpromiserejection

Essentially you need to ensure that any custom async functions being called from your tests need to implement a try/catch.

It makes sense that a try/catch block solves the issue because it's a way of catching rejections. Essentially all Promises in tests should catch or handle reject.

Temirtator commented 1 year ago

mostly, If you met such type of problem you need to take an attention to asynchrous test, perhaps problem related with this

johnmutuma5 commented 1 year ago

For me, my problem was with not mocking a dependency exhaustively when some components in the dependency were being used in the component I was testing. For instance

import { A, B } from "dependency";

MyComponent => ({condition}) => {
  if (condition) 
    return <A /> 
  else
    return <B />
}

in my test

// note B is not mocked, it will be undefined
jest.mock("dependency", () => ({
   A: (props) => Something
}))

// condition as false will require B to be defined
it("shows something", () => {
   <MyComponent condition={false} />
})

This would throw this error until I fully mocked the dependency like this (to ensure B is not undefined in the mock):


// note B will now be defined as the unmocked version
jest.mock("dependency", () => ({
   ...jest.requireActual("dependency"),
   A: (props) => Something
}))

While my component also had some async work, that was never the problem.

Try to check if you have some things that are undefined possibly due to mocking.

lazy-b commented 1 year ago

全体起立! 在 setupTests.js 或者出现问题的单元测试文件添加下面的代码,完美解决!!!

process.on('unhandledRejection', (reason) => {});

参考:https://2ality.com/2016/04/unhandled-rejections.html

kostyaostapuk commented 11 months ago

I was trying to run the craco tests and I got the error:

Test suite failed to run
Call retries were exceeded
at ChildProcessWorker.initialize (node_modules/jest-worker/build/workers/ChildProcessWorker.js:193:21)

I added the option for Node.js for craco test command:

NODE_OPTIONS=--unhandled-rejections=warn craco test

My package.json:

"scripts": {
"test": "NODE_OPTIONS=--unhandled-rejections=warn craco test" }

marcostomasello commented 4 months ago

In my case, it was caused by some unit tests where I forgot to return the promise. Once I added the return keyword it showed me the real reason of the failure (which is specific to my code).