Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to see stacktrace / cause of an error in Jest?

I'm trying to debug a nodeJS app. I have some code which causes an error, a variable is undefined. When I run the code normally, the error is very clear and easy to find:

without jest:

➜  server git:(dc/build) ✗ node test/runner.js
/Users/dc/dev/exiteer/xbot/server/src/mup/Story.js:24
    Logger.logObj('loaded story', {name: doc.name})
                                         ^

ReferenceError: doc is not defined
    at Story.reload (/Users/dc/dev/exiteer/xbot/server/src/mup/Story.js:24:42)
    at Game.reload (/Users/dc/dev/exiteer/xbot/server/src/mup/Game.js:48:16)
    at Object.<anonymous> (/Users/dc/dev/exiteer/xbot/server/test/runner.js:4:10)

Sweet, I can fix it.

Now, Jest has some nice tooling for writing tests so I thought I'd try that.

But the errors are seemingly impossible to track down:

➜  server git:(dc/build) ✗ npm run jest

> [email protected] jest /Users/dc/dev/exiteer/xbot/server
> jest

 PASS  src/index.test.js
(node:23114) UnhandledPromiseRejectionWarning: ReferenceError: doc is not defined
(Use `node --trace-warnings ...` to show where the warning was created)
(node:23114) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:23114) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
 FAIL  src/mup/Actor.test.js
  ● Console

    console.log
      actors undefined

      at Object.<anonymous> (src/mup/Actor.test.js:9:13)

  ● Game.js › can load a story

    expect(received).toHaveLength(expected)

    Matcher error: received value must have a length property whose value must be a number

    Received has value: undefined

       8 | 
       9 |     console.log('actors', game.story.room.name.actors)
    > 10 |     expect(game.story.room.actors).toHaveLength(1);
         |                                    ^
      11 |     const actor = game.story.room.actors[0]
      12 |     const reply = actor.sayTo('hi')
      13 |     expect(reply).toBe('hi back from Sid')

      at Object.<anonymous> (src/mup/Actor.test.js:10:36)

This tells me where my tests failed, but I'd prefer to know where the actual error is. Tests aren't the end goal here, a working app is.

Googling around I found and tried this but it gives the same error message.

node --trace-warnings node_modules/.bin/jest --no-cache

➜  server git:(dc/build) ✗ npm run test

> [email protected] test /Users/dc/dev/exiteer/xbot/server
> node --trace-warnings node_modules/.bin/jest --no-cache

(node:23263) UnhandledPromiseRejectionWarning: ReferenceError: doc is not defined
    at emitUnhandledRejectionWarning (internal/process/promises.js:151:15)
    at processPromiseRejections (internal/process/promises.js:211:11)
    at processTicksAndRejections (internal/process/task_queues.js:98:32)
(node:23263) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)

which gives a tiny bit more info but an

    at emitUnhandledRejectionWarning (internal/process/promises.js:151:15)
    at processPromiseRejections (internal/process/promises.js:211:11)
    at processTicksAndRejections (internal/process/task_queues.js:98:32)

This is not very helpful for debugging my code.

Also Jest seems to swallow all console.log as if it's doing the best to make debugging as painful as possible. When your environment doesn't even log, its a real WTF moment.

like image 658
dcsan Avatar asked Jul 14 '20 14:07

dcsan


People also ask

What is a Stacktrace error?

Stack trace error is a generic term frequently associated with long error messages. The stack trace information identifies where in the program the error occurs and is helpful to programmers. For users, the long stack track information may not be very useful for troubleshooting web errors.

How do you throw error in jest?

to use throw to thrown an error in the mocked implementation of yourMockInstance . If we're mocking async functions, we can use mockRejectedValue to mock the value of a rejected promise returned by the async function. test('async test', async () => { const yourMockFn = jest. fn().

What is the stack trace of an error object?

An error’s stack trace contains all the stack frames until its own constructor function. If you want to read more about specific properties of Errorobjects I highly recommend you to read this article on MDN. To throw an error you must use the throwkeyword.

How to get a stack trace for JavaScript when throwing an exception?

There are the following methods by which we can get a stack trace for JavaScript when throwing an exception. Using console.trace: The console object also has a method called console.trace () method, which gives you the trace on the console. Every time when it is called stack trace generate for the function.

What is a stack trace in Node JS?

In some environments, such as Node, Firefox, Chrome, Edge, IE 10+, Opera and Safari 6+, we even have the stackproperty, which contains an error’s stack trace. An error’s stack trace contains all the stack frames until its own constructor function.

What do Java stack traces show you?

This Java stack trace gives us a picture of what the program did, in the order that it did it. A Java stack trace is a snapshot of a moment in time. You can see where your application was and how it got there. That’s valuable insight that you can use a few different ways. Now that you’ve seen what Java stack traces show you, how can you use them?


Video Answer


1 Answers

This was a bug in Node.js or Jest depending on your perspective - I fixed this a few months ago.

It happens because Jest throws errors in JavaScript coming from a different realm - so instanceof Error fails. You can see my PR here.

There is a workaround if you are forced to use old versions of Node or Jest here:

process.on('unhandledRejection', (reason) => {
  console.log(reason); // log the reason including the stack trace
  throw e;
});

We added this hook in Node 1.3 so it should be safe to use in virtually all Node code.

like image 64
Benjamin Gruenbaum Avatar answered Oct 21 '22 11:10

Benjamin Gruenbaum