The nodejs 18 server crashes because of an unhandledRejection sometimes, pointing to the code below. It only happens on prod and is not redproducable locally. The error is getting catched, and because it doesn't happen all the time it's hard to find the reason. I am already rethrowing the error, but it doesn't help.
private async verifySomething(req: Request, res: Response): Promise<void> {
try {
const { type } = req.body;
assert(typeof type === "string");
const something = await this.findSomethingByType(type);
NotFoundError.assert(something);
await this.somethingPolicy.checkSomething(something).catch(Promise.reject(error)); // <-- rethrow here
return await this.doStuff(something, req);
} catch (error) {
await this.doOtherStuff(req, res, error);
}
}
public async checkSomething(something: ISomething | null): Promise<void> {
const [failedAttempts, policies] = await Promise.all([
this.getFailedAttemptCount(something),
this.getPolicies(something)
]);
this.checkRules(something, failedAttempts, policies ? policies : undefined);
this.doSomething(something),
}
private checkRules(something: ISomething | null, failedAttempts?: number, policies?: IPolicies): void {
this.invokeRules(this.getRules(), something, failedAttempts, policies);
}
private getRules(): RuleCallbackType[] {
// if policy fails it throws an error - all synchronous
return [
this.somethingNotFound,
this.hasTriedToManyTimes,
this.isSpecialSomething,
this.hasWrongProperties,
...this.getAdditionalRules()
];
}
private somethingNotFound(something: ISomething | null): asserts somethingis ISomething {
// the other checks are similar to this with void return type
if (something === null) {
throw new SpecialError();
}
}
private hasTriedToManyTimes(something: ISomething | null, failedAttempts?: number): void {
if (Number(failedAttempts) > Policy.MAX_SUCCESSIVE_FAILURES) {
this.logFailedAttempts(something.type); // async but we don't wait for it
throw new SpecialError(); // <-- this is the error causing the crash
}
}
private invokeRules(rules: RuleCallbackType[], something: ISomething, failedAttempts?: number,
policies?: IPolicies
): void {
for (const rule of rules) {
rule.call(this, something, failedAttempts, policies);
}
}
exiting after unhandledRejection, SpecialError SpecialError Error: SpecialError
at SomethingPolicy.hasTriedToManyTimes
at SomethingPolicy.invokeRules
at SomethingPolicy.checkRules
at SomethingPolicy.checkSomething
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at /xyz/BasicSomethingPolicy.ts:25:13 stack=Error: SpecialError
at SomethingPolicy.hasTriedToManyTimes
at SomethingPolicy.invokeRules
at SomethingPolicy.checkRules
at SomethingPolicy.checkSomething
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at /xyz/BasicSomethingPolicy.ts:25:13 stack=Error: SpecialError
I'd like to know the reason behind this, before I try some more workarounds. Could .call(...) be causing this problem?