(Disclaimer: Ich habe keine Lösung, ich habe untersucht, was Exception-Handling in Bezug auf das Drucken von Emoji besonders macht, mit den Tools, die ich auf Windows 10 habe - mit etwas Glück, das vielleicht geplant wurde etwas Licht auf das Thema, und vielleicht jemand wird etwas erkennen und mit einer Lösung kommen)
Sieht aus wie der Ausnahmeberichtscode von Node für Windows-Aufrufe an eine andere Windows-API, die Unicode besser unterstützt.
Sehen wir uns mit Knoten 7.10 Quellen an:
ReportException
→
AppendExceptionLine
→
PrintErrorString
In PrintErrorString
erkennt der Windows-spezifische Abschnitt den Ausgabetyp (tty / Konsole oder nicht) :
- Für nicht-tty / console context wird es auf stderr
gedruckt (z. B. wenn Sie in eine Datei umleiten)
- In einer Cmd-Konsole (ohne Umleitung) wird konvertiert Text mit MultiByteToWideChar()
und dann übergeben das an WriteConsoleW()
.
Wenn ich dein Programm mit ConEmu ausführe (einfacher als standardmäßiges cmd
zu bekommen, um mit Unicode & amp; emoji zu arbeiten - ja, ich hier etwas faul), sehe ich etwas Ähnliches wie das, was du gesehen hast: console.log
kann Emoji nicht drucken, aber die Emoji in der Ausnahmemeldung werden OK gedruckt (sogar das Scroll-Zeichen).
Wenn ich alle Ausgaben in eine Datei umleite ( node test.js > out.txt 2>&1
, ja das funktioniert auch in Windows cmd), bekomme ich in beiden Fällen "sauberen" Unicode.
So scheint es, wenn ein Programm in einer Windows-Konsole auf stdout
oder stderr
druckt, die Konsole vor dem Drucken einige (schlechte) Neucodierungsarbeiten durchführt. Wenn das Programm die Windows-Konsolen-API direkt verwendet (indem es die Konvertierung selbst mit MultiByteToWideChar
ausführt und dann mit WriteConsoleW()
in die Konsole schreibt), zeigt die Konsole das glorreiche, unveränderte Emoji.
Wenn ein JS-Programm console
API verwendet, um Daten zu protokollieren, könnte Node versuchen (unter Windows), die Konsole zu erkennen und dasselbe wie beim Melden von Ausnahmen zu tun. Siehe @ BrianNixons Antwort , die erklärt, was tatsächlich in libuv passiert.