I have a retry decorator that I put over all my http calls for dependency.
Something like:
@retry(3)
callToGoogle(..)
@retry(2)
callToMicrosoft(..)
I need a way to detect which retry attempt is it inside the functions. I don't have the option to add the attempt as a parameter to the function because those functions have optional parameters and different locations in my code call them with different number of parameters.
For some reason when I deploy this source of code to production - the value retryAttempt in function foo is undefined.
Weirdly, this works in unit test - meaning the retryAttempt is populated. I have no idea what this isn't working.
The local test is a node.js process holding my application and the prod environment is kubernetes that runs this process over multiple pods. I don't see a reason why that would matter. Please help me!
Code:
function retrySyncMethod(
times: number,
target: any,
originalMethod: any,
args: any[]): any {
for (var attempt = 1; attempt < times; attempt++) {
const nextAttempt: number = attempt + 1;
target.currAttempt = nextAttempt;
var result = originalMethod.apply(target, args);
return result;
}
}
export function retry(attempts: number):
(target: Object,
propertyKey: string,
descriptor: TypedPropertyDescriptor<any>) => void {
return function (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> {
var originalMethod = descriptor.value;
descriptor.value = function (...args: any[]): any {
var that = this;
try {
return originalMethod.apply(that, args);
} catch (err) {
return retrySyncMethod(attempts, that, originalMethod, args);
}
};
return descriptor;
};
}
@retry(3)
function foo(host: string, path: string, optionaParam?: null) {
const retryAttempt: number = (<any>this).currAttempt;
if (retryAttempt > 2) {
host = "changing host"
}
console.log("Mock Executing http request and throwing an error to simulate the need of retry");
throw Error("Got 500 - throwing error in order to retry");
}