console: don't swallow call stack exceeded errors
Fixes test/parallel/test-console-no-swallow-stack-exceeded.js PR-URL: https://github.com/nodejs/node/pull/19423 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
cde98ce147
commit
d49661bb80
@ -21,15 +21,16 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const { ERR_CONSOLE_WRITABLE_STREAM } = require('internal/errors').codes;
|
||||
const {
|
||||
isStackOverflowError,
|
||||
codes: { ERR_CONSOLE_WRITABLE_STREAM },
|
||||
} = require('internal/errors');
|
||||
const util = require('util');
|
||||
const kCounts = Symbol('counts');
|
||||
|
||||
// Track amount of indentation required via `console.group()`.
|
||||
const kGroupIndent = Symbol('groupIndent');
|
||||
|
||||
let MAX_STACK_MESSAGE;
|
||||
|
||||
function Console(stdout, stderr, ignoreErrors = true) {
|
||||
if (!(this instanceof Console)) {
|
||||
return new Console(stdout, stderr, ignoreErrors);
|
||||
@ -113,17 +114,9 @@ function write(ignoreErrors, stream, string, errorhandler, groupIndent) {
|
||||
|
||||
stream.write(string, errorhandler);
|
||||
} catch (e) {
|
||||
if (MAX_STACK_MESSAGE === undefined) {
|
||||
try {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function a() { a(); }
|
||||
} catch (err) {
|
||||
MAX_STACK_MESSAGE = err.message;
|
||||
}
|
||||
}
|
||||
// console is a debugging utility, so it swallowing errors is not desirable
|
||||
// even in edge cases such as low stack space.
|
||||
if (e.message === MAX_STACK_MESSAGE && e.name === 'RangeError')
|
||||
if (isStackOverflowError(e))
|
||||
throw e;
|
||||
// Sorry, there's no proper way to pass along the error here.
|
||||
} finally {
|
||||
|
@ -569,11 +569,33 @@ function dnsException(err, syscall, hostname) {
|
||||
return ex;
|
||||
}
|
||||
|
||||
let MAX_STACK_MESSAGE;
|
||||
/**
|
||||
* Returns true if `err` is a `RangeError` with an engine-specific message.
|
||||
* "Maximum call stack size exceeded" in V8.
|
||||
*
|
||||
* @param {Error} err
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isStackOverflowError(err) {
|
||||
if (MAX_STACK_MESSAGE === undefined) {
|
||||
try {
|
||||
function overflowStack() { overflowStack(); }
|
||||
overflowStack();
|
||||
} catch (err) {
|
||||
MAX_STACK_MESSAGE = err.message;
|
||||
}
|
||||
}
|
||||
|
||||
return err.name === 'RangeError' && err.message === MAX_STACK_MESSAGE;
|
||||
}
|
||||
|
||||
module.exports = exports = {
|
||||
dnsException,
|
||||
errnoException,
|
||||
exceptionWithHostPort,
|
||||
uvException,
|
||||
isStackOverflowError,
|
||||
message,
|
||||
AssertionError,
|
||||
SystemError,
|
||||
|
18
test/parallel/test-console-no-swallow-stack-overflow.js
Normal file
18
test/parallel/test-console-no-swallow-stack-overflow.js
Normal file
@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
const { Console } = require('console');
|
||||
const { Writable } = require('stream');
|
||||
|
||||
for (const method of ['dir', 'log', 'warn']) {
|
||||
common.expectsError(() => {
|
||||
const out = new Writable({
|
||||
write: common.mustCall(function write(...args) {
|
||||
// Exceeds call stack.
|
||||
return write(...args);
|
||||
}),
|
||||
});
|
||||
const c = new Console(out, out, true);
|
||||
|
||||
c[method]('Hello, world!');
|
||||
}, { name: 'RangeError' });
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user