nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
106.14k stars 28.87k forks source link

console.error unexpectedly turns output red #53661

Open Jason3S opened 1 month ago

Jason3S commented 1 month ago

Related to PR #51629

I'm a bit surprised that this landed without a link to the discussion. #40361 is a feature request, but doesn't have a real discussion around the pros/cons and how it will impact the nodejs ecosystem.

I would have rather seen color added to the formatting of Errors instead of blanket red/yellow for console.error/console.warn.

I realize that in some way, this PR makes the behavior closer to that in the browser, but browsers do not have CLI applications.

I treat console.log and console.error as separate channels. Traditionally stdout is used for output of the program. It contains the result to be used, think grep. stderr is used for diagnostics, status, and messages to the user while the application is running. Color is not implied.

I would rather that this PR implemented color as a opt in vs trying to figure out how to opt out.

Originally posted by @Jason3S in https://github.com/nodejs/node/issues/51629#issuecomment-2198074841

RedYetiDev commented 1 month ago

FWIW I'm +1 on the idea of making the coloring of console opt-in, but that's not my say. (Or just removing it entirely, and having the users handle it themselves)


CC @nodejs/console

RedYetiDev commented 1 month ago

Related to #51503 Related to #51629 Related to #40361 Related to #53665

jasnell commented 1 month ago

I'm +1 on making the colorization opt-in

ruyadorno commented 1 month ago

I'm -1 on making colorization opt-in.

Color has been opt-out in the runtime for as long as I can remember and I would need a much stronger argument to be convinced otherwise.

Although I don't necessarily agree with the current state of things, the console APIs are properly documented as debugging only: https://nodejs.org/docs/latest/api/console.html#console - and as such their output is not meant to be stable. With that in mind, I would advise cli apps that need stable formatting for their output to write to process.stdout and process.stderr instead of relying on console.log and console.error.

MoLow commented 1 month ago

-1 as well. maybe we can find another mitigation. also, coloring is not new for console log since logged items are passed to util.inspect wich adds colors in various cases

joyeecheung commented 1 month ago

Shouldn't the color only be default when the stdout/stderr are TTY? I wonder https://github.com/nodejs/node/issues/53665 is more of a bug of the TTY detection not smart enough

marco-ippolito commented 1 month ago

+1 on making the color opt-in, expect tty maybe

ruyadorno commented 1 month ago

Shouldn't the color only be default when the stdout/stderr are TTY? I wonder https://github.com/nodejs/node/issues/53665 is more of a bug of the TTY detection not smart enough

I remember testing TTY detection and it was working as expected.

cjihrig commented 1 month ago

From what I can tell, the TTY detection is working as expected.

jakebailey commented 1 month ago

Docs or not, I do think console.error's preexisting behavior was expected by most people and is widely used as a canonical way to "print to stderr". I've seen quite a few projects mentioning breakage due to this change who are hoping for it to be reverted. I have personally written code which assumed that console.log would go to stdout such that that info can be piped, while console.error did not and was treated as plain logging.

RedYetiDev commented 1 month ago

FWIW The way I see it, there are few different choices here, such as: 1) Do nothing 2) Revert #51629 3) Make the special colors opt-in 4) Make the special colors opt-out

jasnell commented 1 month ago

What major versions implement the updated colorization? As a compromise here, I'd suggest that we make sure the change is not backported to anything before 22 if it has been already and we retroactively mark it a semver-major change. Keep the new behavior moving forward with the additional documentation,

RedYetiDev commented 1 month ago

What major versions implement the updated colorization?

v20.15.0 (794e450ea7) and v22.2.0 (db76c58d68)

Jason3S commented 1 month ago

FWIW, I think two different things are getting mixed up.

  1. This issue is about arbitrarily adding red/yellow ANSI color codes to all console.error/.warn strings before sending them to stderr.
  2. Colorization -- I like colorization and would like to keep it.

40361 seems to have been the motivating factor for the change. If you ignore the title and read the body of the request, it was asking to colorize the Error title red. That could have been accomplished with through updating util.inspect colors to support customization of Errors.

console.log, .warn, and .error represent different logging levels. They do not imply color. Hence the issue #53665.

My vote:

  1. roll back the change.
  2. Fix #40361 using inspect.
  3. Add the ability to customize the default color for console.log, .warn, and .error.

51629 was a great POC, it has established that some people want color added and others do not. Even so, I do not believe it is the right long term approach on how to add color to console.error/.warn.

MoLow commented 1 month ago

FWIW there is already an option to opt-out from coloring when stderr is tty: FORCE_COLOR=0 node and opt-in when not in tty: FORCE_COLOR=1 node

imranbarbhuiya commented 1 month ago

FWIW there is already an option to opt-out from coloring when stderr is tty: FORCE_COLOR=0 node and opt-in when not in tty: FORCE_COLOR=1 node

It'll opt-out all types of coloring which might have added intentionally by the user and not just console.warn/error right? So people who only want to opt-out from default coloring of warn/error and keep other coloring can't use it

MoLow commented 1 month ago

It'll opt-out all types of coloring which might have added intentionally by the user and not just console.warn/error right? So people who only want to opt-out from default coloring of warn/error and keep other coloring can't use it

that is correct, but why is there an essential difference?

Jason3S commented 1 month ago

It'll opt-out all types of coloring which might have added intentionally by the user and not just console.warn/error right? So people who only want to opt-out from default coloring of warn/error and keep other coloring can't use it

that is correct, but why is there an essential difference?

It is a huge difference.

When I use console.error("Dump: %o", myObject), I'm expecting that in color mode, myObject might be colored. I even have control over its representation: Custom inspection functions on objects.

But, in the current implementation of console.error, I don't have any control over the ANSI Red that is getting injected, it is not possible to remove it from within my own code.

From my perspective, #51629 landed without any formal review of the impact or a design discussion on how to give the best experience. What problem was #51629 solving? It didn't solve #40361, that user was asking for more control over the output of errors. It does not work for that:

Example code:

const error = new Error('This is an error message');
console.error(error);
console.error('This is an error: ', error);
console.error('Just some text.');

Output: Node 20.15.0

image

Here is what #40361 was talking about:

code:

import util from 'node:util';
const error = new Error('This is an error message');
console.error(error);
console.log('We want the Error Title to be Red:');
console.error(util.styleText('red', util.format(error)));

output:

image

I can empathize with #40361, it is impossible to nicely change the format of the Error message.

Why should we keep #51629 when what it does could be easily implemented in user land:

console.error(util.styleText('red', 'My message.'));
joyeecheung commented 1 month ago

I wonder if packages that get broken are intercepting stderr output by monkey patching process.stderr, which is still expected to work in TTY; in that case it seems the colorization should also check whether the process.stderr has been monkey patched.

Jason3S commented 1 month ago

@RedYetiDev,

What are the next steps to take? Should I make a PR that rolls back that change? So far, I see no benefit in keeping #51629.

RedYetiDev commented 1 month ago

I'm not sure, some of the collaborators in this issue may know