@stryker-mutator/core
Version:
The extendable JavaScript mutation testing framework
39 lines • 1.76 kB
JavaScript
import { coreTokens } from './di/index.js';
const signals = Object.freeze(['SIGABRT', 'SIGINT', 'SIGHUP', 'SIGTERM']);
export class UnexpectedExitHandler {
process;
unexpectedExitHandlers = [];
shuttingDown = false;
static inject = [coreTokens.process];
constructor(process) {
this.process = process;
signals.forEach((signal) => process.on(signal, this.processSignal));
}
processSignal = (_signal, signalNumber) => {
// See https://nodejs.org/api/process.html#signal-events, we should exit with 128 + signal number
const exitCode = 128 + signalNumber;
if (this.shuttingDown) {
// Second signal: force immediate exit without waiting for exit handlers.
console.error('Forced exit. Received signal again while shutting down.');
this.process.exit(exitCode);
return; // `process.exit` is stubbed in tests, so return explicitly to prevent fall-through
}
this.shuttingDown = true;
if (this.unexpectedExitHandlers.length === 0) {
this.process.exit(exitCode);
return; // `process.exit` is stubbed in tests, so return explicitly to prevent fall-through
}
// Run async handlers before exiting. Signal handlers keep the event loop alive,
// so we can await async work here.
void Promise.allSettled(this.unexpectedExitHandlers.map((handler) => handler())).then(() => {
this.process.exit(exitCode);
});
};
registerHandler(handler) {
this.unexpectedExitHandlers.push(handler);
}
dispose() {
signals.forEach((signal) => this.process.off(signal, this.processSignal));
}
}
//# sourceMappingURL=unexpected-exit-handler.js.map