NomCereal
NomCereal

Reputation: 113

Jest - UnhandledPromiseRejection - Received promise resolved instead of rejected

Jest is throwing me the following error message --

node:internal/process/promises:245
          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: expect(received).rejects.toThrowError()

Received promise resolved instead of rejected
Resolved to value: undefined".] {
  code: 'ERR_UNHANDLED_REJECTION'
}
error Command failed with exit code 1.

I am quite unsure how to proceed forward. The error message from Jest reads like it is failing because the promise resolves and it expects an error to be thrown...but is upset when an error is thrown and says it is unhandled? I must be understanding this totally wrong.

Here is my test --

    describe('credentials test', () => {
        it('without credentials', async () => {
            const provider = new Provider();
            provider.configure(testConfig);
            const spyon = jest.spyOn(Credentials, 'get').mockImplementation(() => {
                return Promise.reject('err');
            });

            const action = async () => {
                await provider.create({
                    param: val,
                });
            };

            expect(action()).rejects.toThrowError();
            spyon.mockRestore();
        });
    });

And the code being tested --

    public async create(
        params: CreateInput
    ): Promise<CreateOutput> {
        const cmd = new Command(params);
        const client = this._init();

        try {
            const credentialsOK = await this._ensureCredentials();
            if (!credentialsOK) {
                logger.error(NO_CREDS_ERROR_STRING);
                throw Error;
            }

            const output = await client.send(cmd);
            return output;
        } catch (error) {
            logger.error(`error - ${error}`);
        }
    }

    private async _ensureCredentials() {
        return await Credentials.get()
            .then(credentials => {
                if (!credentials) return false;
                const cred = Credentials.shear(credentials);
                logger.debug('set credentials', cred);
                this._config.credentials = cred;

                return true;
            })
            .catch(error => {
                logger.warn('ensure credentials error', error);
                return false;
            });
    }

Upvotes: 9

Views: 22462

Answers (2)

Urshit Sheth
Urshit Sheth

Reputation: 47

Handled from jest.config.js

setupFiles: ['<rootDir>/jest.setup.js'],

jest.setup.js

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

Upvotes: 0

mikemaccana
mikemaccana

Reputation: 123410

I'm writing this answer to help others with the prob but the source is @bergi's comment above. You need to use await with expect(someFunction()).rejects.toThrowError(). This will look like:

  it(`Should throw an error when bad things happen`, async () => {
    const result = doThing()
    await expect(result).rejects.toThrowError(`oh no`);
  });

In regards to the OP's follow up question:

expect(received).rejects.toEqual() -- Received promise resolved instead of rejected -- Resolved to value: undefined

That's a separate issue - as Jest says, the function you're expecting to throw is returning undefined rather than throwing an error. You should add something like throw new Error('oh no') to the code you're calling (though again that's a separate question).

Upvotes: 9

Related Questions