From 48d1ea5e7fc918ae9f74d8472785720a13a755e6 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Sat, 15 Jun 2019 13:54:50 +0200 Subject: [PATCH] assert: special handle identical error names in instance checks This makes sure that using `assert.throws()` or `assert.rejects()` in combination with Error classes log appropriate error messages in case the expected and received constructor name are identical but not part of the same prototype chain. PR-URL: https://github.com/nodejs/node/pull/28263 Reviewed-By: Rich Trott Reviewed-By: Benjamin Gruenbaum Reviewed-By: James M Snell --- lib/assert.js | 10 +++++++--- test/parallel/test-assert.js | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/assert.js b/lib/assert.js index 0b256e604ee..94104ee881c 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -620,10 +620,14 @@ function expectedException(actual, expected, message, fn) { generatedMessage = true; message = 'The error is expected to be an instance of ' + `"${expected.name}". Received `; - // TODO: Special handle identical names. if (isError(actual)) { - const name = actual.constructor && actual.constructor.name; - message += `"${name || actual.name}"`; + const name = actual.constructor && actual.constructor.name || + actual.name; + if (expected.name === name) { + message += 'an error with identical name but a different prototype.'; + } else { + message += `"${name}"`; + } if (actual.message) { message += `\n\nError message:\n\n${actual.message}`; } diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index 07cf3746965..48b44ce29b4 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -25,6 +25,7 @@ const common = require('../common'); const assert = require('assert'); const { inspect } = require('util'); +const vm = require('vm'); const { internalBinding } = require('internal/test/binding'); const a = assert; @@ -1344,3 +1345,17 @@ assert.throws( } ); } + +assert.throws( + () => { + const script = new vm.Script('new RangeError("foobar");'); + const context = vm.createContext(); + const err = script.runInContext(context); + assert.throws(() => { throw err; }, RangeError); + }, + { + message: 'The error is expected to be an instance of "RangeError". ' + + 'Received an error with identical name but a different ' + + 'prototype.\n\nError message:\n\nfoobar' + } +);