jtlapp / node-cleanup

installs custom cleanup handlers that run on exiting node
MIT License
164 stars 10 forks source link

no way to disable uncaught exception handler? #14

Open tony-gutierrez opened 6 years ago

tony-gutierrez commented 6 years ago

I dont want the process.exit functionality included in the uncaughtException handler. Is there a way to disable this? I realize i can catch it in the cleanup handler but there is no hint that it is uncaughtException other then the exitCode 1....which could be thrown by another lib.

theTestTube commented 4 years ago

In my use case, with node v12.16.3, when running cleanup beneath REPL an [ERR_INVALID_REPL_INPUT]: Listeners for uncaughtException cannot be used in the REPL error is produced,

repl.js:253
        throw new ERR_INVALID_REPL_INPUT(
        ^
Uncaught:
TypeError [ERR_INVALID_REPL_INPUT]: Listeners for `uncaughtException` cannot be used in the REPL
    at process.<anonymous> (repl.js:253:15)
    at process.emit (events.js:322:22)
    at process.EventEmitter.emit (domain.js:482:12)
    at process.emit (~\AppData\Roaming\npm\node_modules\ts-node\node_modules\source-map-support\source-map-support.js:495:21)
    at _addListener (events.js:353:14)
    at process.addListener (events.js:401:10)
    at Object.install (~\node_modules\node-cleanup\node-cleanup.js:118:17)
    at new Device (~\device\[eval].ts:8:16)
    at ~\device\[eval].ts:1:14
    at Script.runInThisContext (vm.js:120:20) {
      code: 'ERR_INVALID_REPL_INPUT'
    }

To reproduce the issue consider the Device class below and run let device = new Device("myDevice"); under REPL.

import cleanup from "node-cleanup";
import Debug from "debug";

const debug = Debug('device');

class Device {
    constructor(readonly deviceId: string) {
        cleanup(this._halt);
    }

    async halt(): Promise<void> {
    }

    private _halt(exitCode: number | null, signal: string | null): boolean {
        if (signal) {
            if (this) {
                debug("halting on %s: %s", signal, this.deviceId);
                this.halt();
                debug("halted: %s", this.deviceId);
            } else debug("device was garbage collected and halted on %s", signal);
            process.kill(process.pid, signal);
            cleanup.uninstall();
        } else if (this) debug("halted with exit code %d: %s", exitCode, this.deviceId);
        else debug("halted with exit code %d", exitCode);

        return false;
    }
}
theTestTube commented 4 years ago

As per NodeJS 14.4 REPL docs this is normal.

A workaround consists on ignoring cleanup when REPL execution is detected, which can actually be a bit tricky,

try {
    const repl = __dirname;
    cleanup(this._halt);
} catch (err) {
    debug("REPL running was detected, cleanup disabled: %s", this.deviceId);
}