From c40ec6395df18850f453bddca8c5efffd99ab0f7 Mon Sep 17 00:00:00 2001 From: Peter Somogyvari Date: Fri, 16 Oct 2020 14:40:57 -0700 Subject: [PATCH] fix(lib/test): stack traces when res.name is Error, not string When executing tests, the res.name property (as constructed in the ./lib/test.js#_assert method) is actually not a string but the error that was thrown. This (assuming edge case) combined with extra.error and opts.error both being falsy ends up producing this situation where feeding res.name into the Error constructor makes the original error's stack trace disappear and only it's message remains with the newly constructed Error instance holding a completely generic stack trace that's internal to tape's source code (and therefore not much use when a test is failing due to some code is throwing exceptions instead of failing an assertion). Signed-off-by: Peter Somogyvari --- lib/test.js | 3 ++- test/async-await.js | 3 ++- test/promise_fail.js | 10 ++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/test.js b/lib/test.js index 4d6182c0..463e86d0 100644 --- a/lib/test.js +++ b/lib/test.js @@ -257,7 +257,8 @@ Test.prototype._assert = function assert(ok, opts) { this._ok = !!(this._ok && ok); if (!ok && !res.todo) { - res.error = defined(extra.error, opts.error, new Error(res.name)); + var anError = res.name instanceof Error ? res.name : new Error(res.name); + res.error = defined(extra.error, opts.error, anError); } if (!ok) { diff --git a/test/async-await.js b/test/async-await.js index 02aff917..bdc4fc0a 100644 --- a/test/async-await.js +++ b/test/async-await.js @@ -219,7 +219,8 @@ tap.test('async-error', function (t) { ' ---', ' operator: fail', ' stack: |-', - ' Error: Error: oopsie', + ' Error: oopsie', + ' at Test.myTest ($TEST/async-await/async-error.js:$LINE:$COL)', ' [... stack stripped ...]', ' ...', '', diff --git a/test/promise_fail.js b/test/promise_fail.js index ddc93412..eb512bed 100644 --- a/test/promise_fail.js +++ b/test/promise_fail.js @@ -34,7 +34,10 @@ tap.test('callback returning rejected promise should cause that test (and only t ' ---', ' operator: fail', ' stack: |-', - ' Error: Error: rejection message', + ' Error: rejection message', + ' at $TEST/promises/fail.js:$LINE:$COL', + ' [... stack stripped ...]', + ' at Test. ($TEST/promises/fail.js:$LINE:$COL)', ' [... stack stripped ...]', ' ...', '# after', @@ -78,7 +81,10 @@ tap.test('subtest callback returning rejected promise should cause that subtest ' ---', ' operator: fail', ' stack: |-', - ' Error: Error: rejection message', + ' Error: rejection message', + ' at $TEST/promises/subTests.js:$LINE:$COL', + ' [... stack stripped ...]', + ' at Test. ($TEST/promises/subTests.js:$LINE:$COL)', ' [... stack stripped ...]', ' ...', '# sub test that should pass',