Can't control stringification of error messages
See original GitHub issuePrerequisites
- Checked that your issue hasn’t already been filed by cross-referencing issues with the
faq
label - Checked next-gen ES issues and syntax problems by using the same environment and/or transpiler configuration without Mocha to ensure it isn’t just a feature that actually isn’t supported in the environment in question or a bug in your code.
- ‘Smoke tested’ the code to be tested by running it outside the real test suite to get a better sense of whether the problem is in the code under test, your usage of Mocha, or Mocha itself
- Ensured that there is no discrepancy between the locally and globally installed versions of Mocha. You can find them with:
node node_modules/.bin/mocha --version
(Local) andmocha --version
(Global). We recommend that you not install Mocha globally.
Description
I’ve been running into issues with error stringification, due to the change that was introduced in https://github.com/mochajs/mocha/pull/2101.
My application adds additional context to error messages in development by adding additional properties to the Error
objects, and I’ve struggled to get Mocha to display any of this additional information.
The main problem is that the code used to ensure that message is a string is this (from lib/reporters/list.js):
if (err.message && typeof err.message.toString === 'function') {
message = err.message + '';
} else if (typeof err.inspect === 'function') {
message = err.inspect() + '';
} else {
message = '';
}
The problem with that is that you can (theoretically) customize how Mocha displays your error messages, but only if the error doesn’t have a message
property that includes a toString
method, which seems like an odd edge case for error messages.
So in my case, I have the following chain of events making this impossible.
- All of my errors have a
message
property, and it is always aString
String.prototype
has atoString
method that just returns itself- You can’t replace the
toString
method on a string.
This also means that if you are using a custom Error
subclass that includes an inspect
method, then whether that function gets called or not can be affected by what the message
property contains. It will work if that property doesn’t have a toString
method, but won’t work if it does.
The only way I’ve found to make this work is with new Error( undefined )
, which seems to be the only way to get a value into the message property that doesn’t have a toString
method, unfortunately that fixes it for Mocha but makes it useless for everything else.
My recommendation would be to just swap the order of the checks, if the error has an inspect
method it seems like that should be used regardless of what the message is.
Steps to Reproduce
describe( 'should show my extra props', () => {
it( 'with a string error', () => error( 'something' ) );
it( 'without a string error', () => error( undefined ) );
} );
function error( msg ) {
const err = new Error( msg );
err.inspect = function inspect() {
return `Custom Formatted Error: ${msg}`;
};
throw err;
}
Expected behavior: [What you expect to happen]
Both of the test should fail with an error message that gets displayed with a prefix of Custom Formatted Error
.
Actual behavior: [What actually happens]
Only one of them gets formatted correctly.
should show my extra props
1) with a string error
2) without a string error
0 passing (8ms)
2 failing
1) should show my extra props
with a string error:
Error: something
at error (mocha-repro.js:7:15)
at Context.it (mocha-repro.js:2:36)
at processImmediate (internal/timers.js:443:21)
2) should show my extra props
without a string error:
Custom Formatted Error: undefined
Error
at error (mocha-repro.js:7:15)
at Context.it (mocha-repro.js:3:39)
at processImmediate (internal/timers.js:443:21)
Reproduces how often: [What percentage of the time does it reproduce?]
100% reproducible
Versions
- The output of
mocha --version
andnode node_modules/.bin/mocha --version
: 6.2.0
Issue Analytics
- State:
- Created 4 years ago
- Reactions:1
- Comments:5 (3 by maintainers)
It was not assertions where I was seeing this, the problem I was having was with tests that were failing because they were throwing actual exceptions from buggy code, and this was preventing me from getting the information that I needed to determine why those exceptions had been thrown.
Another year, another crippling bug in essential tooling that seems to receive zero attention from developers…