nyc: fix: correctly report error numbers in stack traces

When I take my mocha code out of nyc, the line numbers are correct, so I know that nyc is to blame.

https://github.com/stevenvachon/incomplete-url/commit/9c6eb47e3b98916b3697af3ad472f7cd73ffffd7

produces: https://travis-ci.org/stevenvachon/incomplete-url/jobs/248590761

I get the same result when adding source-map-support:

nyc --source-map --produce-source-map mocha test --require=source-map-support/register

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 18
  • Comments: 27 (7 by maintainers)

Commits related to this issue

Most upvoted comments

@bcoe @kpdecker how can we help to get this issue fixed? Do you need a small(er) application to reproduce the problem? Something else? Please let us know!

I believe we are having the same problem as @bajtos (Hi, we use Loopback đź‘‹ !) - we are not using ts-node. We have TSC compile sourceMaps (as external .map files, not inline) and we have mocha --register source-map-support/register.

When we run mocha itself, everything works great. When we run nyc mocha, the stack traces get weird. Sometimes they show the TS file with a bad line number, sometimes they show the .js file.

The solution I identified was to manually add the following lines to my test suite at the top of test/index.js

require('source-map-support').install({
  hookRequire: true
});

Then running nyc it will generate source maps out of the box, and my test code now correctly asks source-map-support to “load” the source maps nyc generates and now my stack traces for new Error() etc are correct.

npr nyc -a -r html -- node test/index.js

In newer versions of Node.js, you could also try running with --enable-source-maps.

@JaKXz I think this is the same issue that I was about to report. This example uses only mocha and nyc.

https://github.com/alex028502/nyc-line-number-issue

I have put --cache false. I hope that works.

I have the same problem. Is there any solution?

We are experiencing similar problem in https://github.com/strongloop/loopback-next:

  • Both src and test is transpiled using TypeScript, external source maps are used

  • mocha.opts registers source-map-support

  • When the tests are run via nyc mocha, some of the error stack-trace frames are pointing to original TypeScript sources but others are pointing to transpiled JavaScript - see https://github.com/strongloop/loopback-next/pull/884#issuecomment-359623533

    at TestController.hello
      ([cut]/packages/rest/dist/test/integration/http-handler.integration.js:6:8854)
    at ControllerRoute.invokeHandler
      ([cut]/packages/rest/src/router/routing-table.ts:47:50)
    
  • When the tests are run via mocha, all error stack-trace frames are pointing to original TypeScript sources

    at TestController.hello
      ([cut]/packages/rest/test/integration/http-handler.integration.ts:471:17)
    at ControllerRoute.invokeHandler 
      ([cut]/packages/rest/src/router/routing-table.ts:318:46)
    

(cc @raymondfeng)

Is there any update on the matter? using @ianldgs workaround feels wrong as the test run twice and as he states it is just a workaround.

I believe this is a breaking issue on both the JavaScript and the TypeScript environment as being able to read meaningful stacktraces in unit and integration tests is a core reason for writing tests in the first place.

Having that problem too. Using nyc + mocha + ts-node. Source maps activated everywhere.


Edit: found a workarround!

"scripts": {
  ...
  "test": "cross-env TS_NODE_FILES=true mocha --opts mocha.opts",
  "posttest": "cross-env TS_NODE_FILES=true nyc mocha --opts mocha.opts",
  ...
},

if tests fails, posttest won’t run and stacktrace without nyc will be output.

It would be nice to, once and for all, correctly report line numbers in stack traces in as many common nyc configurations as possible.

A good start would be to add some unit tests to istanbul-lib-instrument. to test the simple cases.

This issue is blocked by https://github.com/evanw/node-source-map-support/issues/239. The issue is that nyc source-maps are inline but node-source-map-support does not look at inline source-maps by default.

I faced a similar issue with --produce-source-map not appearing to work a few days back, even with source-map-support (in my case, required in app code via require('source-map-support').install({hookRequire: true})).

I think I’ve gotten it working after adding both the --eager and --cache false flags. @stevenvachon maybe you could verify if that fixes things?

To me it feels like it has something to do with instrumenter caching - if I recall correctly, there was also some weirdness along the lines of:

  1. Remove those 2 flags.
  2. Error trace shows correct line number.
  3. Shift error-causing code 1 line up.
  4. Error trace shows wrong line number.
  5. Shift error-causing code back down.
  6. Error trace shows correct line number.

I may not have remembered the above steps/results entirely accurately, but it definitely felt anomalous so that could be a potential lead.