diff --git a/lib/runner.js b/lib/runner.js index 67e6fbabdb..cceacc9533 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -231,15 +231,7 @@ Runner.prototype.fail = function(test, err) { ++this.failures; test.state = 'failed'; - if (!(err instanceof Error || (err && typeof err.message === 'string'))) { - err = new Error( - 'the ' + - type(err) + - ' ' + - stringify(err) + - ' was thrown, throw an Error :)' - ); - } + err = string2Error(err); try { err.stack = @@ -731,6 +723,7 @@ Runner.prototype.uncaught = function(err) { debug('uncaught undefined exception'); err = undefinedError(); } + err = string2Error(err); err.uncaught = true; var runnable = this.currentRunnable; @@ -993,6 +986,27 @@ function filterLeaks(ok, globals) { }); } +/** + * + * Check that the given object is an Error, convert it at such on the contrary + * + * @api private + * @param {Object} err + * @return {Error} + */ +function string2Error(err) { + if (!(err instanceof Error || (err && typeof err.message === 'string'))) { + err = new Error( + 'the ' + + type(err) + + ' ' + + stringify(err) + + ' was thrown, throw an Error :)' + ); + } + return err; +} + /** * Array of globals dependent on the environment. * diff --git a/test/unit/throw.spec.js b/test/unit/throw.spec.js index 6aca25750c..b9f520178b 100644 --- a/test/unit/throw.spec.js +++ b/test/unit/throw.spec.js @@ -26,6 +26,24 @@ describe('a test that throws', function() { }); }); + describe('non-extensible', function() { + it('should not crash if throwing non-extensible type', function(done) { + var test = new Test('im async and throw string async', function(done2) { + process.nextTick(function() { + throw 'error'; + }); + }); + suite.addTest(test); + runner = new Runner(suite); + runner.on('end', function() { + expect(runner.failures, 'to be', 1); + expect(test.state, 'to be', 'failed'); + done(); + }); + runner.run(); + }); + }); + describe('undefined', function() { it('should not pass if throwing sync and test is sync', function(done) { var test = new Test('im sync and throw undefined sync', function() {