Troubleshooting Exceeded Maximum Retry Attempts in Jest Call

Close-up of hands typing on an illuminated RGB keyboard with code on screen

Exceeding the maximum retry attempts in a Jest call can be frustrating. To resolve this issue, you can follow these steps: 

  • Firstly, check out the solution provided in the answer titled “Testing a Function Containing setTimeout()”;
  • Additionally, explore documentation and articles on utilizing fakeAsync() and tick() for testing asynchronous code;
  • If these approaches fail, consider wrapping your test case in a setTimeout() function with the same time delay as in your component. 

If you’re a new Vue and Jest tester facing errors during specific test runs or encountering issues with particular test cases, this guide aims to assist you in troubleshooting.

Solutions for “Call Retries Exceeded” Error in Jest Testing

Question

I’m encountering a problem with my Jest test and using Node.js version 12.10.0. Is there an alternative to using setTimeout in this scenario?

test('demo code', async () => {

        const cc = await projectSetup(project);

        const onNotification = jest.fn();

        cc.sendNotification();

        await waitForExpect(() => {

            expect(onNotification).toHaveBeenCalledTimes(2);

        });

    });

The error message is:

Call retries were exceeded

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

Solution 1: Utilize Jest Fake Timers

Incorporate jest.useFakeTimers(); immediately after your imports.

jest.useFakeTimers();

test('demo code', async () => {

        const cc = await projectSetup(project);

        const onNotification = jest.fn();

        cc.sendNotification();

        await waitForExpect(() => {

            expect(onNotification).toHaveBeenCalledTimes(2);

        });

    });

This approach resolved the issue in this scenario.

Solution 2: Address Promise Handling in Tests

The issue was linked to the handling of promises across Jest tests, and running tests individually may help identify the precise error.

After isolating a test, the below error was identified, different from the initial Call retries were exceeded error:

[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 “TypeError:

Cannot read property 'code' of undefined".] {

  code: 'ERR_UNHANDLED_REJECTION'

}

After integrating the catch block into the async service API function, the test case executed smoothly, indicating that the problem resided within the catch block. You might want to consider applying the same strategy to determine if it produces comparable outcomes for you.

Here are the configurations I’m utilizing:

  • Node.js version: 15.13.0;
  • npm version: 7.8.0.

And just for fun, here’s a humorous notation: 26.6.3

Solution 3:

The test was successfully executed by following these steps:

Install using: npm i -D jest-canvas-mock

Modify the jest.config.ts file to include the following:

export default {

...

testEnvironment: "jsdom",

setupFiles: ["jest-canvas-mock"],

}

Solution 4:

  • Execute npm doctor using the latest npm release;
  • This utility is excellent for identifying issues related to ownership and permissions.

Takeaway: Ensure to check the ownership and permissions of files and folders.

Error: Call Retries Exceeded during ng build for ES5 Bundles

Fingers on a laptop keyboard with blurry code in the background

During the generation of ES5 bundles for differential loading via the ng build command, an error is encountered. The error message indicates an unhandled exception: “Call retries were exceeded.” This issue is observed with the following versions:

  • angular-cli: 8.3.20;
  • Angular: 8.2.7;
  • Node: 12.12.1.

The error is further elaborated in the logs, mentioning:

[error] Error: Call retries were exceeded at ChildProcessWorker.initialize

This error pertains to the failure to initialize a child process worker due to exceeded call retries.

Solution 1:

The issue with @angular/cli can be addressed by referring to comment #16515, which recommends updating to version >= 8.3.22.

Original:

There’s a memory shortage issue affecting the build process, as indicated by related problems #15493 and #16515 on angular-cli.

To resolve this, follow these steps:

  1. Upgrade Node.js to the latest version, using: 12.14.0;
  2. Increase memory allocation during the build process by modifying the package.json;
  3. Change the “build” script to: node –max_old_space_size=4096 node_modules/@angular/cli/bin/ng build;
  4. This allocates 4GB of memory. Adjust as needed based on your project’s size;
  5. Consider temporary solutions by using earlier releases of angular/cli and build-angular.
"devDependencies": {

    "@angular-devkit/build-angular": "0.803.20",

    "@angular/cli": "8.3.20",

If memory usage remains a concern, you can disable differential loading to reduce memory consumption during the build process.

Solution 2:

The problem resolution came from adjusting the tsconfig.json file.

A recent update in @angular-devkit/build-angular has altered the approach to differential loading. To address this issue in your Ionic project, simply change the “target” value in your tsconfig.json file from “es2015” to “es5”.

Solution 3:

Use the following command to increase Node’s memory limit and initiate an Angular build:

node --max_old_space_size=6144 ./node_modules/@angular/cli/bin/ng build

Solution 4:

A similar issue was encountered during the production build process with Node v10, leading to exceptions. To overcome this, the “target” option in the tsconfig.json file was adjusted to “es5”. This change, however, eliminated differential loading, which was unintended. After upgrading to Node v14, these issues were resolved, allowing for the reversion to using “target”: “es2015” without encountering exceptions.

This problem manifested specifically when trying to build an Angular project within an Ionic environment, resulting in the error: “Error: Call retries were exceeded” traced back to the jest-worker module at ChildProcessWorker.initialize and onExit within the project’s directory.

Fixing Jest ChildProcessWorker Init Error in Angular Tests

Question:

When running ng test (or nx test when using nrwl/nx) for Angular applications, an error might occur related to component testing, leading to tests hanging. This is observed while utilizing Jest for unit testing. The specific error encountered is “Call retries were exceeded at ChildProcessWorker.initialize.”

Solution:

The issue may stem from using a setTimeout within the AfterViewInit() lifecycle hook of a component. To address and resolve this timer-related problem in tests, consider the following approaches:

  • Review methods for testing functions that incorporate setTimeout(). It’s helpful to consult both the Angular documentation and related articles on how to effectively use fakeAsync() and tick() for testing asynchronous operations;
  • If the direct approach does not yield results, try wrapping your test case in a setTimeout() function, matching the timeout duration used within the component. This technique can help synchronize the test environment with the component’s timing, potentially bypassing the error;
  • It’s important to note that discrepancies in testing frameworks can lead to misunderstandings. For instance, if encountering issues with expect() statements not behaving as anticipated, verify the testing framework and assertion libraries being used. Jest’s expect() may not have the same properties or matchers as those used in other frameworks like Mocha and Chai, as highlighted by some tutorials or documentation. Always ensure compatibility and correct usage of testing utilities in your project’s context.

Jest Worker Encountered Child Process Exceptions

A young man coding on a computer in a dark room

A Vue and Jest testing beginner seeks guidance on understanding and resolving a recurring error in their tests. Need help analyzing and identifying the underlying issue. Error details below:

 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)

Test Failure:

test("signupAsUser logs results if email is provided", async () => {

  const consoleSpy = jest.spyOn(console, "log");

  const email = ref("[email protected]");

  const { signupAsUser } = useSignup(email);

  await signupAsUser();

  expect(consoleSpy).toHaveBeenCalledWith("USER:", mockSignup);

});

These are the files presently being tested, which include the Vue file, as well as the TypeScript file.

import { Ref } from "vue";

import { useApolloClient } from "@vue/apollo-composable";

import { ValidatedUser } from "@/models";

import { gql } from "graphql-tag";

import router from "@/router";

const query = gql`

  query Signup($input: Signup) {

    signup(input: $input) {

      __typename

      token

      user {

        emailAddress

        id

      }

    }

  }

`;

/**

 * Retrive apollo client and provide useSignup

 * function to validate input and execute Signup process.

 *

 * @param emailAddress - reactively wrapped emailAddress address of the user signing up.

 * @returns useSignup composition functionality.

 */

export default function useSignup(emailAddress: Ref): {

  signupAsUser: () => Promise;

} {

  const { resolveClient } = useApolloClient();

  /**

   * Execute the Signup process for the specified user values.

   */

  /**

   *

   */

  async function signupAsUser(): Promise {

    console.log("emailAddress " + emailAddress.value);

    if (emailAddress.value.length < 5) {

      console.log("here");

      return;

    } else {

      const client = resolveClient();

      const variables = {

        input: { username: emailAddress.value },

      };

      // const response = await client.query({query, variables});

      console.log("here");

      // const validatedUser: ValidatedUser = response.data.signup;

      // console.log("USER:", validatedUser);

      console.log("emailAddress: ", variables);

    }

    router.push({ path: "/signup/verify" });

  }

  return { signupAsUser };

}

Could you be guided towards the source of the timeout or the potential origin of the error?

A solution found while facing a similar issue involves the following steps:

  • One option is to include –maxWorkers 2 in the command for your Jest test;
  • It seems that this issue stems from a combination of factors, with unhandled promise rejections being among them;
  • To address it, consider experimenting with integrating waitFor into your code to see if it brings about any improvements.
import { waitFor } from 'test/test-utils'

test("signupAsUser logs results if email is provided", async() => {

  const consoleSpy = jest.spyOn(console, "log");

  const email = ref("[email protected]");

  const {

    signupAsUser

  } = useSignup(email);

  await waitFor(() => signupAsUser());

  expect(consoleSpy).toHaveBeenCalledWith("USER:", mockSignup);

});

<p> This answer shed more light. </p>

Encountering difficulties in building with Angular 11, the error message states: 

"[error] Error: Call retries were exceeded at ChildProcessWorker.initialize (C:\Users\AkashGupta\source\repos\LMS\LMS\ClientApp\node_modules\jest-worker\build\workers\ChildProcessWorker.js:230:21) at …"

Conclusion

Overcoming Jest Worker’s child process exceptions and exceeding retry limits may require an understanding of asynchronous code testing techniques, properly handling promises, and efficiently allocating memory during the build process. However, the difficulty lies in correctly identifying the contributing factors causing the error. Once the source of the error is correctly identified, it becomes easier to apply the above-mentioned solutions.

Leave a Reply

Your email address will not be published. Required fields are marked *