Skip to content

Unhandled rejections cause test script exit #4794

Closed
@mdr

Description

@mdr

We're getting an error with one of our tests in our CRA app. Our test looks a bit like the following:

import React from 'react'
import { shallow } from 'enzyme'

const flushPromises = () => new Promise(resolve => setImmediate(resolve))

const fetchTheData = jest.fn()

class MyContainerComponent extends React.Component {
  state = { error: null }

  async componentDidMount() {
    try {
      await fetchTheData()
    } catch (e) {
      this.setState({ error: 'There was a problem' })
      throw e // rethrow so it gets handled by a generic unhandled promise rejection handler (e.g. Sentry)
    }
  }

  render() {
    return <p>{this.state.error}</p>
  }
}

it('should handle errors calling the API', async () => {
  fetchTheData.mockImplementation(() => Promise.reject(new Error('something bad happened')))

  const component = shallow(<MyContainerComponent />)

  await flushPromises()
  expect(component.update()).toIncludeText('There was a problem')
})

However, it blows up on npm test with:

RUNS  src/App.test.js
/Users/matt/misc-repos/promise-rejection-oddity/node_modules/react-scripts/scripts/test.js:20
  throw err;
  ^

Error: something bad happened
    at fetchTheData.mockImplementation (/Users/matt/misc-repos/promise-rejection-oddity/src/App.test.js:26:56)
    at mockConstructor (/Users/matt/misc-repos/promise-rejection-oddity/node_modules/jest-mock/build/index.js:288:37)
    at MyContainerComponent.componentDidMount (/Users/matt/misc-repos/promise-rejection-oddity/src/App.test.js:13:13)
    at /Users/matt/misc-repos/promise-rejection-oddity/node_modules/enzyme/build/ShallowWrapper.js:126:20
    at Object.batchedUpdates (/Users/matt/misc-repos/promise-rejection-oddity/node_modules/enzyme-adapter-react-16/build/ReactSixteenAdapter.js:342:22)
    at new ShallowWrapper (/Users/matt/misc-repos/promise-rejection-oddity/node_modules/enzyme/build/ShallowWrapper.js:125:24)
    at shallow (/Users/matt/misc-repos/promise-rejection-oddity/node_modules/enzyme/build/shallow.js:19:10)
    at Object.<anonymous>.it (/Users/matt/misc-repos/promise-rejection-oddity/src/App.test.js:28:41)
    at Object.asyncFn (/Users/matt/misc-repos/promise-rejection-oddity/node_modules/jest-jasmine2/build/jasmine-async.js:68:30)
    at resolve (/Users/matt/misc-repos/promise-rejection-oddity/node_modules/jest-jasmine2/build/queueRunner.js:38:12)
    at new Promise (<anonymous>)
    at mapper (/Users/matt/misc-repos/promise-rejection-oddity/node_modules/jest-jasmine2/build/queueRunner.js:31:21)
    at Promise.resolve.then.el (/Users/matt/misc-repos/promise-rejection-oddity/node_modules/p-map/index.js:46:16)
npm ERR! Test failed.  See above for more details.

This behaviour appears to be because there is an unhandled rejection, and in react-scripts/scripts/test.js:

// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
  throw err;
});

So, I guess I wanted to understand whether what we're trying to do in our test is bad -- we have an unhandled rejection, but that's intentional, and not a problem in the browser environment (we have a global error handler that will deal with it). Is CRA being overly enthusiastic in causing the script to crash in these cases? Should we be dealing with things in a different way?

The other oddity is that most of the time, when all the tests in our actual app's test suite are run together, the test passes. It's only when run in isolation that we trigger the unhandledRejection event listener and the script exits. Any ideas on why that might be the case?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions