diff options
-rw-r--r-- | cli/rt/02_console.js | 9 | ||||
-rw-r--r-- | cli/tests/unit/console_test.ts | 15 |
2 files changed, 22 insertions, 2 deletions
diff --git a/cli/rt/02_console.js b/cli/rt/02_console.js index 363a95d90..0eb7f0aac 100644 --- a/cli/rt/02_console.js +++ b/cli/rt/02_console.js @@ -196,8 +196,13 @@ return String(value[customInspect]()); } catch {} } - // Might be Function/AsyncFunction/GeneratorFunction - const cstrName = Object.getPrototypeOf(value).constructor.name; + // Might be Function/AsyncFunction/GeneratorFunction/AsyncGeneratorFunction + let cstrName = Object.getPrototypeOf(value)?.constructor?.name; + if (!cstrName) { + // If prototype is removed or broken, + // use generic 'Function' instead. + cstrName = "Function"; + } if (value.name && value.name !== "anonymous") { // from MDN spec return `[${cstrName}: ${value.name}]`; diff --git a/cli/tests/unit/console_test.ts b/cli/tests/unit/console_test.ts index df1420345..00a5927b1 100644 --- a/cli/tests/unit/console_test.ts +++ b/cli/tests/unit/console_test.ts @@ -347,6 +347,21 @@ unitTest(function consoleTestStringifyCircular(): void { }); /* eslint-enable @typescript-eslint/explicit-function-return-type */ +unitTest(function consoleTestStringifyFunctionWithPrototypeRemoved(): void { + const f = function f() {}; + Reflect.setPrototypeOf(f, null); + assertEquals(stringify(f), "[Function: f]"); + const af = async function af() {}; + Reflect.setPrototypeOf(af, null); + assertEquals(stringify(af), "[Function: af]"); + const gf = function gf() {}; + Reflect.setPrototypeOf(gf, null); + assertEquals(stringify(gf), "[Function: gf]"); + const agf = function agf() {}; + Reflect.setPrototypeOf(agf, null); + assertEquals(stringify(agf), "[Function: agf]"); +}); + unitTest(function consoleTestStringifyWithDepth(): void { // eslint-disable-next-line @typescript-eslint/no-explicit-any const nestedObj: any = { a: { b: { c: { d: { e: { f: 42 } } } } } }; |