async-retry
async-retry copied to clipboard
Jest test fails without retry
"dependencies": { "@azure/event-hubs": "^5.6.0", "@azure/eventgrid": "^4.5.0", "@azure/eventhubs-checkpointstore-blob": "^1.0.1", "@azure/storage-blob": "^12.8.0", "@hapi/joi": "^17.1.1", "@nestjs/common": "^8.2.6", "@nestjs/core": "^8.2.6", "@nestjs/mongoose": "^8.0.1", "@nestjs/platform-express": "^8.2.6", "@nestjs/swagger": "^5.2.0", "@sendgrid/client": "^7.4.2", "async-retry": "1.3.1", "axios": "^0.21.1", "azure-eventgrid": "^1.6.0", "azure-iothub": "^1.14.1", "azure-storage": "^2.10.4", "class-transformer": "^0.5.1", "class-validator": "^0.13.2", "config": "^3.3.6", "flat": "^5.0.2", "fs-extra": "^10.0.0", "hot-shots": "^8.3.0", "mongoose": "^5.13.9", "ms-rest-azure": "^3.0.0", "nanoid": "^3.3.1", "nestjs-pino": "^2.5.0", "pino-noir": "^2.2.1", "qs": "^6.10.1", "raw-body": "^2.4.1", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.5.4", "swagger-ui-express": "^4.1.6" }, "devDependencies": { "@nestjs/testing": "^8.1.2", "@types/express": "^4.17.13", "@types/flat": "5.0.2", "@types/fs-extra": "^9.0.13", "@types/hapi__joi": "^17.1.4", "@types/jest": "^27.0.2", "@types/multer": "^1.4.2", "@types/nanoid": "^2.1.0", "@types/node": "^14.17.20", "@types/pino": "^6.3.11", "@types/supertest": "^2.0.10", "@typescript-eslint/eslint-plugin": "^3.7.1", "@typescript-eslint/parser": "^3.7.1", "eslint": "^7.8.1", "eslint-plugin-import": "^2.24.2", "eslint-plugin-prefer-arrow": "^1.2.2", "jest": "^27.2.4", "prettier": "^1.15.3", "supertest": "^4.0.2", "ts-jest": "^27.0.5", "ts-node": "9.0.0", "tsc-watch": "^4.2.9", "tsconfig-paths": "3.9.0", "typescript": "^4.0.2", "wait-on": "^5.3.0" }, "jest": { "moduleFileExtensions": [ "js", "json", "ts" ], "rootDir": "src", "testRegex": ".spec.ts$", "transform": { "^.+\.(t|j)s$": "ts-jest" }, "coveragePathIgnorePatterns": [ "/src/core/validators" ], "coverageDirectory": "../coverage", "testEnvironment": "node" }
please refer to my above configurations. I am facing an issue while testing the async-retry library as below.
const flushPromises = (): unknown => new Promise(resolve => setImmediate(resolve));
it('should retry method execution till success', async () => { const verifyMethod = jest.fn().mockResolvedValue('verified'); const testObject = { testKey: 'testValue', methodToExecute : jest.fn() .mockRejectedValueOnce(new errors.ThrottlingError('ThrottlingError')) .mockRejectedValueOnce(new errors.ThrottlingError('ThrottlingError')) .mockImplementationOnce(function(input) { // eslint-disable-next-line no-invalid-this return verifyMethod(input, this.testKey); }) }; const promise = throttlingErrorHandler.handleOnError( testObject.methodToExecute.bind(testObject), [ 'testInput' ], { iothub: 'iothub1', deviceId: 'testdevice', operation: 'verifyMethod' } ); await flushPromises(); jest.runAllTimers(); await flushPromises(); jest.runAllTimers(); await flushPromises(); const result = await promise; expect(result).toEqual('verified'); expect(verifyMethod).toHaveBeenCalledWith('testInput', testObject.testKey); expect(testObject.methodToExecute).toHaveBeenCalledTimes(3); expect(mockMailService.sendMail).not.toHaveBeenCalled(); });
while executing this getting jest timeout exceed error.
below are my code snipped. public async handleOnError<T>( asyncMethodToExecute: (...args) => Promise<T>, methodArguments: unknown[], context: { iothub: string; deviceId: string; operation: string }, runForever = false ): Promise<T> {
this.appLoggerService.warn(`Throttling/IotHubQuotaExceededError on ${context.iothub}`, ThrottlingErrorHandler.name);
const throttlingErrorConfiguration = await this.throttlingErrorConfigurationDbService.getConfiguration();
if (!throttlingErrorConfiguration) {
this.appLoggerService.warn('Throttling error configuration not available', ThrottlingErrorHandler.name);
return null;
}
const isMaxRetriesEnabled = throttlingErrorConfiguration.maxRetriesEnabled;
const maxRetries = isMaxRetriesEnabled ? throttlingErrorConfiguration.maxRetries : -1;
// fixed interval in seconds after which operation is tried again
const maxJitterIntervalInSeconds = throttlingErrorConfiguration.maxJitterIntervalInSeconds;
const sendMailAfterNumberOfAttempts = throttlingErrorConfiguration.sendMailAfterNumberOfAttempts;
const milliseconds = 1000;
return await retry(async (bail, attempt) => {
try {
const result = await asyncMethodToExecute(...methodArguments); // method context (this) should already be set by caller
return result;
} catch (error) {
if (error instanceof errors.ThrottlingError
|| error instanceof errors.IotHubQuotaExceededError) {
this.appLoggerService.warn(`Error: ${error.name} on ${context.iothub}`, ThrottlingErrorHandler.name);
if (attempt % sendMailAfterNumberOfAttempts === 0 && throttlingErrorConfiguration.sendGrid.isEnabled) {
this.appLoggerService.error(`Error: ${error.name} on ${context.iothub}, sending mail`, ThrottlingErrorHandler.name);
void this.mailService.sendMail(
throttlingErrorConfiguration.sendGrid.mailTo,
throttlingErrorConfiguration.sendGrid.mailCc,
throttlingErrorConfiguration.sendGrid.templateId,
{
iothub: context.iothub,
deviceId: context.deviceId,
operation: context.operation,
error: error.name
}
);
}
throw error;
} else {
bail(error);
}
}
},
{
retries: maxRetries > 0 && !runForever ? maxRetries - 1 : undefined, // subtract 1 as initial attempt itself is a retry
forever: !isMaxRetriesEnabled || runForever,
maxTimeout: maxJitterIntervalInSeconds * milliseconds,
randomize: true
});
}
the above retry function doesn't retry when an error is thrown.
kindly review and suggest what is wrong. it was working with jest 25.* version but not working with 27.* version.
my node version is 16.11.0 & npm version is 8.0.0