Winston not displaying error details
I think what you're missing is format.errors({ stack: true })
in winston.createLogger
.
const logger = winston.createLogger({ level: 'debug', format: format.combine( format.errors({ stack: true }), print, ), transports: [new transports.Console()],});
See this GitHub thread for more information.
The reason this is happening is because the interesting Error
object properties, like .stack
, are non-enumerable. Some functions check if the their parameters are Error
instances, like console.error
, and other functions ignore all non-enumerable properties, like winston.<log-level>
and JSON.stringify
.
> console.error(new Error('foo'))Error: foo at repl:1:15 at Script.runInThisContext (vm.js:124:20) ...(abbr)> JSON.stringify(new Error('foo'))'{}'
All that said, it's horrible usability to have an error logger essentially ignore errors... I just lost too much time to this.
A quick and dirty way would be to log err.stack
:
logger.error(err.stack);
A more elaborate method would be to implement a custom format specifically for Error
instances. There's some example code on how to implement that in this Github issue.
Using format.
const { combine, timestamp, label, printf } = winston.format;const myFormat = printf(info => { if(info instanceof Error) { return `${info.timestamp} [${info.label}] ${info.level}: ${info.message} ${info.stack}`; } return `${info.timestamp} [${info.label}] ${info.level}: ${info.message}`;});winston.createLogger({ level: "info", format: combine( winston.format.splat(), label({ label: filename}), timestamp(), myFormat, ), transports: [ // // - Write to all logs with level `info` and below to `combined.log` // - Write all logs error (and below) to `error.log`. // new winston.transports.File({ filename: path.join(os.tmpdir(), "test", "test.log"), level: "info" }), ],});