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
- Register exception handlers: logger.exceptions.handle(new winston.transports.File({ filename: 'exceptions.log' })).
- If no handlers are wanted, set exitOnError: false in createLogger options to silence the warning and keep default Node exit behavior.
- 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
- Pair exitOnError: true with at least one logger.exceptions.handle(...) registration.
- Register exception transports at logger creation, not lazily.
- Review configs after refactors: exitOnError without exceptionHandlers is a smell.
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
- winston: not exiting process.
- { %s } was removed in winston@3.0.0.
- { %s } was removed in winston@3.0.0. Use a custom winston.fo
- Logger is required to handle exceptions
- ExceptionStream requires a TransportStream instance.
AI-assisted analysis of winstonjs/winston@ff0b79de85 (2026-08-31).
Data as JSON: /api/errors/db9a5df1d876a210.
Report an issue: GitHub.