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

Better error message for unsupported command prompt code page #29324

Closed
Hakerh400 opened this issue Aug 26, 2019 · 3 comments
Closed

Better error message for unsupported command prompt code page #29324

Hakerh400 opened this issue Aug 26, 2019 · 3 comments
Labels
tty Issues and PRs related to the tty subsystem. windows Issues and PRs related to the Windows platform.

Comments

@Hakerh400
Copy link
Contributor

  • Version: v12.9.0
  • Platform: Windows 8.1 (6.3.9600 Build 9600)
  • Subsystem: console

If the console code page is 65001, printing a character outside ASCII range disables stdout. For example

console.log('\u0409 test');

prints nothing (no output, no errors). Exit code is 0.
Using process.stdout throws an error:

process.stdout.write('\u0409 test\n');

gives:

events.js:186
      throw er; // Unhandled 'error' event
      ^

Error: write EIO
�[90m    at afterWriteDispatched (internal/stream_base_commons.js:146:25)�[39m
�[90m    at writeGeneric (internal/stream_base_commons.js:137:3)�[39m
�[90m    at WriteStream.Socket._writeGeneric (net.js:698:11)�[39m
�[90m    at WriteStream.Socket._write (net.js:710:8)�[39m
�[90m    at doWrite (_stream_writable.js:428:12)�[39m
�[90m    at writeOrBuffer (_stream_writable.js:412:5)�[39m
�[90m    at WriteStream.Writable.write (_stream_writable.js:302:11)�[39m
    at Object.<anonymous> (C:\Users\Thomas\Downloads\1.js:2:16)
�[90m    at Module._compile (internal/modules/cjs/loader.js:936:30)�[39m
�[90m    at Object.Module._extensions..js (internal/modules/cjs/loader.js:947:10)�[39m
Emitted 'error' event on WriteStream instance at:
�[90m    at errorOrDestroy (internal/streams/destroy.js:107:12)�[39m
�[90m    at onwriteError (_stream_writable.js:443:5)�[39m
�[90m    at onwrite (_stream_writable.js:470:5)�[39m
�[90m    at internal/streams/destroy.js:49:7�[39m
�[90m    at WriteStream.dummyDestroy [as _destroy] (internal/process/stdio.js:7:3)�[39m
�[90m    at WriteStream.destroy (internal/streams/destroy.js:37:8)�[39m
�[90m    at afterWriteDispatched (internal/stream_base_commons.js:146:17)�[39m
�[90m    at writeGeneric (internal/stream_base_commons.js:137:3)�[39m
�[90m    at WriteStream.Socket._writeGeneric (net.js:698:11)�[39m
�[90m    at WriteStream.Socket._write (net.js:710:8)�[39m {
  errno: �[32m'EIO'�[39m,
  code: �[32m'EIO'�[39m,
  syscall: �[32m'write'�[39m
}

Using fs module works somewhat:

require('fs').writeSync(process.stdout.fd, '\u0409 test\n');

Output:

Љ test

Command prompt internal command more works fine, it prints Љ test. I guess Node.js does not support the 65001 codepage, which is ok, but maybe better error message would be appropriate (if the default codepage is 65001, it may be hard for users to find out what the problem is, since console.log gives no output at all).

Possibly related: #11470 and #11469

@Fishrock123 Fishrock123 added tty Issues and PRs related to the tty subsystem. windows Issues and PRs related to the Windows platform. labels Aug 27, 2019
@bnoordhuis
Copy link
Member

The reason console.log() is silent is because console._ignoreErrors === true.

As to providing a better error message: Windows doesn't really give us anything beyond "something went wrong."

The error happens deep inside libuv (src/win/tty.c) when it calls GetConsoleScreenBufferInfo() or one of the SetConsole*() functions. They fail with a generic error that libuv reports as UV_EIO.

@Hakerh400
Copy link
Contributor Author

Even with console._ignoreErrors === false no output is generated if any file name on the stack trace contains unsupported characters. But, for example, Python's error is more user-friendly:

Traceback (most recent call last):
  File "test.py", line 1, in <module>
    print(u'\u0409test')
LookupError: unknown encoding: cp65001

Node.js can call GetACP if the write operation fails and if the code page is unsupported, display an appropriate error. I spent some time trying to fix this, but seems like it is not worth that effort for such an edge case.

@bnoordhuis
Copy link
Member

I've been trying to reason about why it fails with the UTF-8 code page. Libuv is pretty much code page-agnostic.

It uses the wide-character Windows APIs (e.g. WriteConsoleW() rather than WriteConsoleA()) to display text, and converts from UTF-8 to UTF-16 before passing it down.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tty Issues and PRs related to the tty subsystem. windows Issues and PRs related to the Windows platform.
Projects
None yet
Development

No branches or pull requests

3 participants