winstonjs/winston · warning

winston: not exiting process.

Error message

winston: not exiting process.

What it means

The companion warning emitted in the same _uncaughtException branch: after detecting exitOnError=true with zero handlers, winston prints 'winston: not exiting process.' and sets doExit=false so the process survives. It is informational — winston declined to exit because there were no handlers to flush exceptions to.

Source

Thrown at lib/winston/exception-handler.js:179

   * process.
   * @param {Error} err - Error to handle
   * @returns {mixed} - TODO: add return description.
   * @private
   */
  _uncaughtException(err) {
    const info = this.getAllInfo(err);
    const handlers = this._getExceptionHandlers();
    // Calculate if we should exit on this error
    let doExit = typeof this.logger.exitOnError === 'function'
      ? this.logger.exitOnError(err)
      : this.logger.exitOnError;
    let timeout;

    if (!handlers.length && doExit) {
      // eslint-disable-next-line no-console
      console.warn('winston: exitOnError cannot be true with no exception handlers.');
      // eslint-disable-next-line no-console
      console.warn('winston: not exiting process.');
      doExit = false;
    }

    function gracefulExit() {
      debug('doExit', doExit);
      debug('process._exiting', process._exiting);

      if (doExit && !process._exiting) {
        // Remark: Currently ignoring any exceptions from transports when
        // catching uncaught exceptions.
        if (timeout) {
          clearTimeout(timeout);
        }
        // eslint-disable-next-line no-process-exit
        process.exit(1);
      }
    }

View on GitHub (pinned to ff0b79de85)

Solutions

  1. Attach at least one exception handler (logger.exceptions.handle(...)) so exitOnError semantics work as intended.
  2. If survival is desired, set exitOnError: false explicitly to document intent and remove the warnings.
  3. If you need guaranteed process exit regardless of winston, add your own process.on('uncaughtException') handler that logs then calls process.exit(1).

Example fix

// before
const logger = winston.createLogger({ exitOnError: true }); // warns and does NOT exit
// after
const logger = winston.createLogger({ exitOnError: true });
logger.exceptions.handle(new winston.transports.Console()); // now exits after handling
Defensive patterns

Strategy: fallback

Validate before calling

const hasHandlers = logger.exceptions.handlers && logger.exceptions.handlers.size > 0;
if (!hasHandlers) {
  // decide explicitly: attach a handler or own the uncaughtException path yourself
  process.on('uncaughtException', (err) => {
    console.error(err);
    process.exit(1);
  });
}

Prevention

When it happens

Trigger: Same as error 16: uncaughtException occurs, handlers.length === 0 and doExit was true; both warn lines print together in exception-handler.js:177-179.

Common situations: Production incidents where an app expected to crash on uncaught exceptions (for a supervisor to restart it) but silently kept running with corrupted state; configs where exitOnError was enabled for restart tooling but exception transports were never attached.

Related errors


AI-assisted analysis of winstonjs/winston@ff0b79de85 (2026-08-31). Data as JSON: /api/errors/9fcf9267f7386a7d. Report an issue: GitHub.