React: TypeError: Cannot read property 'body' of null

Created on 21 May 2019  路  17Comments  路  Source: facebook/react

This method:

https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react-dom/src/client/getActiveElement.js

Is throwing this error in jest:

image

I realize that this method is checking only when the document is undefined. However, using jest looks that is setting sometimes the document to null, causing this error.

To reproduce it, I'm testing a callback that is using an async task:

 const asyncTask = useCallback(async (data) => {
    dispatch({ type: 'FETCH' })

    try {
      const res = await MyService.asyncMethod(data)
      dispatch({ type: 'SUCCESS', data: res })
    } catch (e) {
      dispatch({ type: 'ERROR' }) // This dispatch throw this error in jest
    }
  }, [])

About the test, I'm just mocking the service and testing the different scenarios.

I imagine that is related that the dispatch from the useReducer, that it's used inside the catch, is fired when the component maybe is unmount? @gaearon In this case how can I do a safer dispatch inside a callback method?

Needs More Information

Most helpful comment

I have the same issue with react testing library, the only difference is that the test pass locally while fails on CI.

All 17 comments

I tried to do this:

 const dispatchSafe = useSafeDispatch(dispatch)

 const asyncTask = useCallback(async (data) => {
    dispatchSafe({ type: 'FETCH' })

    try {
      const res = await MyService.asyncMethod(data)
      dispatchSafe({ type: 'SUCCESS', data: res })
    } catch (e) {
      dispatchSafe({ type: 'ERROR' }) // This dispatchSafe throw the error in jest
    }
  }, [])

When useSafeDispatch is:

export default function useSafeDispatch(dispatch) {
  const dispatchSafe = useRef(dispatch)

  useEffect(() => () => {
    dispatchSafe.current = () => null
  }, [])

  return dispatchSafe.current
}

However, this doesn't solve the problem. Maybe I'm doing something wrong?

could you make a repro with codesandbox, or a git repo? can't say without more info.

I'm also having this issue. In my case it only happens when there is a console.log inside the catch.

No error:

async componentDidMount() {
  try {
    const helpMenu = await MenuService.getMenuAyuda();
    this.setState({ helpMenuArray: helpMenu });
  } catch (error) {}
}

Error:

async componentDidMount() {
  try {
    const helpMenu = await MenuService.getMenuAyuda();
    this.setState({ helpMenuArray: helpMenu });
  } catch (error) { console.log(error) }
}

Also seeing this issue. Pretty much the same try catch as @cristiam86

I'm also seeing the same error "TypeError: Cannot read property 'body' of null".
Would changing if (typeof doc === 'undefined') in https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react-dom/src/client/getActiveElement.js to if (doc == null) make sense?

Please share a codesandbox repro, or even a link to a git repo that reproduces this problem.

I also encountered this issue today. It looks like global.document is being set to null when Jest's JSDOM environment is being torn down:
https://github.com/facebook/jest/blob/72c920e4f8feff5f2b319c4111da8c989de54995/packages/jest-environment-jsdom/src/index.ts#L109

Since getActiveElement never checks for null, we're seeing this error.

This might just be a problem with my test though, because it seems that getActiveElement is being invoked after Jest thinks the test finished.

Can anybody provide a reproducing case please? :-) That's the fastest way to get an issue fixed.

Closing this, happy to reopen if someone shares a reproducing case.

I'm hitting this as well. It's hard to reproduce since it doesn't occur on every run. Only noticed after implementing a bunch of tests and merging my changes, which caused others builds to break (randomly). Makes jest feel pretty flaky.

This definitely seems to be related to async thunks. Definitely still a big current issue, so don't understand why it's closed.

Note: I checked one of my failing async thunk actions and it didn't have any console.log so not seeing that correlation on my end. This is a private repo so unfortunately can't share.

The most likely cause is that there鈥檚 some asynchronous work pending after your test completes, and it tried to update the dom after jest finishes running its tests and cleansup the jsdom instance. There鈥檚 not much that React can do here, since it has to be fixed in the test itself, by either cancelling that work, or waiting till it finishes before exiting the test.

That said, it鈥檚 hard to comment without a reproducing example. Keeping this issue open wouldn鈥檛 serve a purpose. If you can share a git repo with a reduced usecase that reproduces the error, even if only intermittently, I would be happy to help debug or give some pointers.

...
There鈥檚 not much that React can do here, since it has to be fixed in the test itself, by either cancelling that work, or waiting till it finishes before exiting the test.
...

That's not entirely true as React could have accepted this PR and the issue would have been solved generally on their end.

The PR doesn鈥檛 solve the bug, it hides it.

@threepointone I've come up with a reproducible example, although to be fair it would still need investigation to pin down exact/specific cause:

https://github.com/ivarprudnikov/test-react-enzyme-body-null

Hey folks, here is another reproduction of this issue with React and Jest (using React Testing Library this time): https://repl.it/repls/PeskyStimulatingBetaversion

It makes sense that whenever this happens the fix should be within the test itself, ultimately. However, the current error message is not very obvious.

There is already an example of such message here: https://github.com/facebook/react/blob/3e94bce765d355d74f6a60feb4addb6d196e3482/packages/shared/invokeGuardedCallbackImpl.js#L78. The getActiveElement check could also do something like that.

And of course in both of these situations checking for null in addition to undefined would also be helping to correctly show this descriptive message.

So, again, it is true that the root cause is ultimately outside of React code, but this could be a better developer experience when diagnosing it. Hope this helps and thanks for your tireless efforts!

I have the same issue with react testing library, the only difference is that the test pass locally while fails on CI.

@gaearon https://codesandbox.io/s/thirsty-snowflake-y5reo?file=/src/App.js

this is my attempt at a minimal recreation. the reason i would actually want to hit an endpoint is for doing automated integration testing, which i believe is a valid usecase.

Was this page helpful?
0 / 5 - 0 ratings