From 9a8dec0b2413a665b961533f1fada034a80ddd65 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Thu, 13 Apr 2017 11:56:36 -0400 Subject: [PATCH] repl: handle unexpected error objects This commit allows the repl's domain error handler to process unexpected error formats, such as primitives. --- lib/repl.js | 24 ++++++++++++++++-------- test/parallel/test-repl-sigint.js | 2 +- test/parallel/test-repl.js | 21 +++++++++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index 3a56dd675008f9..dfcbd02c5c20c2 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -282,17 +282,25 @@ function REPLServer(prompt, self._domain.on('error', function debugDomainError(e) { debug('domain error'); const top = replMap.get(self); + var out; internalUtil.decorateErrorStack(e); - if (e instanceof SyntaxError && e.stack) { + + if (!((e instanceof Error) && typeof e.stack === 'string' && + e.stack.length > 0)) { + out = util.inspect(e); + } else if (e instanceof SyntaxError) { // remove repl:line-number and stack trace - e.stack = e.stack - .replace(/^repl:\d+\r?\n/, '') - .replace(/^\s+at\s.*\n?/gm, ''); - } else if (e.stack && self.replMode === exports.REPL_MODE_STRICT) { - e.stack = e.stack.replace(/(\s+at\s+repl:)(\d+)/, - (_, pre, line) => pre + (line - 1)); + out = e.stack + .replace(/^repl:\d+\r?\n/, '') + .replace(/^\s+at\s.*\n?/gm, ''); + } else if (self.replMode === exports.REPL_MODE_STRICT) { + out = e.stack.replace(/(\s+at\s+repl:)(\d+)/, + (_, pre, line) => pre + (line - 1)); + } else { + out = e.stack; } - top.outputStream.write((e.stack || e) + '\n'); + + top.outputStream.write(out + '\n'); top.bufferedCommand = ''; top.lines.level = []; top.displayPrompt(); diff --git a/test/parallel/test-repl-sigint.js b/test/parallel/test-repl-sigint.js index 61bc75cc6ffe67..b284a0e95377b1 100644 --- a/test/parallel/test-repl-sigint.js +++ b/test/parallel/test-repl-sigint.js @@ -38,7 +38,7 @@ child.stdout.once('data', common.mustCall(() => { child.on('close', function(code) { assert.strictEqual(code, 0); assert.ok( - stdout.includes('Script execution interrupted.\n'), + stdout.includes('Script execution interrupted.'), `Expected stdout to contain "Script execution interrupted.", got ${stdout}` ); assert.ok( diff --git a/test/parallel/test-repl.js b/test/parallel/test-repl.js index fb0fca7bd9275d..09ab454a790234 100644 --- a/test/parallel/test-repl.js +++ b/test/parallel/test-repl.js @@ -134,6 +134,27 @@ function error_test() { // Uncaught error throws and prints out { client: client_unix, send: 'throw new Error(\'test error\');', expect: /^Error: test error/ }, + // Throws primitive and prints out + { client: client_unix, send: 'throw null;', + expect: 'null' }, + // Throws Object without toString() method and prints out + { client: client_unix, send: 'throw Object.create(null);', + expect: '{}' }, + // Throws Object with bad toString() method and prints out + { + client: client_unix, + send: 'var e = { toString() { throw new Error(\'test\'); } }; throw e;', + expect: /{ toString: \[Function: toString\] }/ + }, + // Throws Symbol and prints out + { client: client_unix, send: 'throw Symbol(\'test\');', + expect: /^Symbol\(test\)/ }, + // Throws Error without stack and prints out + { + client: client_unix, + send: 'var e = new Error(\'test error\'); delete e.stack; throw e;', + expect: /^\[Error: test error\]/ + }, // Common syntax error is treated as multiline command { client: client_unix, send: 'function test_func() {', expect: prompt_multiline },