Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error.message being appended to info.message #1660

Open
1 of 2 tasks
spfellers opened this issue Jun 19, 2019 · 2 comments · May be fixed by #1664
Open
1 of 2 tasks

Error.message being appended to info.message #1660

spfellers opened this issue Jun 19, 2019 · 2 comments · May be fixed by #1664

Comments

@spfellers
Copy link

Please tell us about your environment:

  • winston version?
    • winston@2
    • winston@3
  • node -v outputs: v8.11.4
  • Operating System? macOS
  • Language? all

What's the problem?

Errors should not be appended to the message property.

const {createLogger, format, transports} = require('winston');
const logger = createLogger({
    level: 'info',
    format: format.printf(info => `${info.level}: ${info.message}`),
    transports: [new transports.Console()],
    exitOnError: false
});
logger.error('Error Message:', new Error('This is an Error Log'));
logger.info('Object Message:', {a: 'lamb', b: 'cow'});

// results in
// error: Error Message:This is an Error Log
// info: Object Message:

What do you expect to happen instead?

Errors should not be forced onto the message property, thats what format.errors() is for.
If I want to get a stack trace for errors formatted properly I would do:

const {createLogger, format, transports} = require('winston');
const logger = createLogger({
    level: 'info',
    format: format.printf(info => `${info.level}: ${info.message} ${info.stack || ''}`),
    transports: [new transports.Console()],
    exitOnError: false
});
logger.error('Error Message:', new Error('This is an Error Log'));
logger.info('Object Message:', {a: 'lamb', b: 'cow'});

// results in
// error: Error Message:This is an Error Log Error: This is an Error Log
//           <stack trace>
//           <stack trace>
//           <stack trace>
//           <stack trace>
//           <stack trace>
//           <stack trace>
//           <stack trace>
// info: Object Message:

Problem: error.message gets printed twice because its on the stack and the message

I would expect the error message to only get appended to the message if you use format.errors().

@codyzu
Copy link

codyzu commented Jul 17, 2019

Looks like #1664 is trying to fix this. In the meantime, my solution is to use a custom formatter that "undos" that concatenation:

const {format} = require('winston');

const fixErrors = format(info => {
  // Only modify the info it there was an error
  if (info.stack === undefined) {
    return info;
  }

  const {message} = info;

  // Get the original error message
  const errorMessage =
    info[Symbol.for('splat')] &&
    info[Symbol.for('splat')][0] &&
    info[Symbol.for('splat')][0].message;

  // Check that the original error message was concatenated to the message
  if (
    errorMessage === undefined ||
    message.length <= errorMessage.length ||
    !message.endsWith(errorMessage)
  ) {
    return info;
  }

  // Slice off the original error message from the log message
  info.message = message.slice(0, errorMessage.length * -1);
  return info;
});

module.exports = fixErrors;

And finally, use it like so:

const winston = require('winston');
const fixErrors = require('./fix-errors');

const logger = winston.loggers.add('myLogger', {
  format: winston.format.combine(winston.format.splat(), fixErrors(), winston.format.printf(info => `${info.level.toUpperCase()} ${info.message} ${info.stack === undefined ? '' : info.stack}`)),
  transports: coreTransports,
});

const error = new Error('something bad happened');
logger.error('was doing this and', error);

Resulting in:

ERROR was doing this and Error: something bad happened <rest of the stack>

@tom-milner
Copy link

tom-milner commented Dec 28, 2019

I ran into this problem today, and created the following formatter to un-concatenate the messages:

const messageFormat = format(info => {
    if (info.level == "error") {
        const errorMessage = info[Symbol.for("splat")][0].message;
        info.message = info.message.replace(errorMessage, "");
    }
    return info
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants