@stryker-mutator/core
Version:
The extendable JavaScript mutation testing framework
44 lines (37 loc) • 1.6 kB
text/typescript
import { Mutant } from '@stryker-mutator/api/core';
import { Logger } from '@stryker-mutator/api/logging';
import { ChildProcessCrashedError } from '../child-proxy/child-process-crashed-error.js';
import { OutOfMemoryError } from '../child-proxy/out-of-memory-error.js';
import { ResourceDecorator } from '../concurrent/index.js';
import { CheckerResource } from './checker-resource.js';
export class CheckerRetryDecorator extends ResourceDecorator<CheckerResource> implements CheckerResource {
constructor(
producer: () => CheckerResource,
private readonly log: Logger,
) {
super(producer);
}
public async check(checkerName: string, mutants: Mutant[]): ReturnType<CheckerResource['check']> {
return this.tryAction(() => this.innerResource.check(checkerName, mutants));
}
public async group(checkerName: string, mutants: Mutant[]): ReturnType<CheckerResource['group']> {
return this.tryAction(() => this.innerResource.group(checkerName, mutants));
}
private async tryAction<T>(act: () => Promise<T>): Promise<T> {
try {
return await act();
} catch (error) {
if (error instanceof ChildProcessCrashedError) {
if (error instanceof OutOfMemoryError) {
this.log.warn(`Checker process [${error.pid}] ran out of memory. Retrying in a new process.`);
} else {
this.log.warn(`Checker process [${error.pid}] crashed with exit code ${error.exitCode}. Retrying in a new process.`, error);
}
await this.recover();
return act();
} else {
throw error; //oops
}
}
}
}