winstonjs/winston · warning

winston: exitOnError cannot be true with no exception handle

Error message

winston: exitOnError cannot be true with no exception handlers.

What it means

In exception-handler.js _uncaughtException, when an uncaught exception arrives and there are no exception handlers/transports registered but exitOnError resolves to true, winston warns 'exitOnError cannot be true with no exception handlers.' and forces doExit = false instead of killing the process. It alerts you that your exitOnError=true setting has no handlers to run before exit.

Source

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

  /**
   * Logs all relevant information around the `err` and exits the current
   * 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. Register exception handlers: logger.exceptions.handle(new winston.transports.File({ filename: 'exceptions.log' })).
  2. If no handlers are wanted, set exitOnError: false in createLogger options to silence the warning and keep default Node exit behavior.
  3. If handlers are added dynamically, ensure they exist before an uncaughtException can occur (register at logger creation).

Example fix

// before
const logger = winston.createLogger({ exitOnError: true }); // no exception handlers
// after
const logger = winston.createLogger({ exitOnError: true });
logger.exceptions.handle(new winston.transports.File({ filename: 'exceptions.log' }));
Defensive patterns

Strategy: validation

Validate before calling

if (logger.exitOnError === true && logger.exceptions.handlers.size === 0) {
  logger.exceptions.handle(new winston.transports.File({ filename: 'exceptions.log' }));
}

Prevention

When it happens

Trigger: logger.exitOnError === true (or exitOnError callback returning true) while logger.exceptions.handlers is empty / no exceptions transports added, and an uncaughtException is caught by winston's handler machinery.

Common situations: Setting exitOnError: true in createLogger options but never calling logger.exceptions.handle(...) ; removing exception transports at runtime so handlers.length becomes 0; copying a logger config where exceptions handling was dropped during refactor.

Related errors


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