teroi
teroi

Reputation: 1087

Unhandled rejections in mocha tests from native code

I am getting "unhandled rejection" messages in mocha tests but I am at lost what is the exact source of the problem since this happens asynchronously.

I know that I can add an event listener for the global unhandledRejection event like:

process.on('unhandledRejection', function(reason)  {
     console.error(reason);
     process.exit(1);
});

but that doesn't really help, since the trace is then like follows:

{ Error: ENOENT: no such file or directory, open '/tmp/testfile.json'
    at Error (native)
  cause: 
   { Error: ENOENT: no such file or directory, open '/tmp/testfile.json'
       at Error (native)
     errno: -2,
     code: 'ENOENT',
     syscall: 'open',
     path: '/tmp/testfile.json' },
  isOperational: true,
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '/tmp/testfile.json' }

The problem is the same with the node's inbuilt handler. No backtrace.

Apparently I don't get a proper backtrace because the rejection happens in the native fs module. If I try to run just the test where this trace happens, it doesn't happen at all. It is probably because of a runaway promise that was set up somewhere "earlier". The specified /tmp/ path doesn't exist anywhere in the test code or the actual implementation code. The testfile.json does exist but not in that path.

I am running mocha 3.5.3 with node 6.5.0.

So the question then is: how to narrow down to find the problematic code?

Upvotes: 1

Views: 525

Answers (2)

teroi
teroi

Reputation: 1087

One generic approach. Bisect the problem like:

  1. move some test suite files to a separate directory so that they are not executed during the tests
  2. Rerun mocha
  3. Observe if the fail message persists
  4. If yes, continue moving more files. If not, problematic file was one of the last moved ones.

Then continue bisecting the particular file that is causing the trouble. Comment away code until the problematic code is not executed.

Upvotes: 0

emilsivervik
emilsivervik

Reputation: 11

I'm not sure that it will help, but you can also get the Promise as an argument from the unhandledRejection listener to maybe get some more helpful output. Docs here

process.on('unhandledRejection', (reason, p) => {
  console.log('Unhandled Rejection at:', p, 'reason:', reason);
  // application specific logging, throwing an error, or other logic here
});

Upvotes: 1

Related Questions