question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

componentDidCatch and act not working as expected

See original GitHub issue

👋 I think I found a bug 🙂

https://github.com/calebeby/preact-act-bug

I have a feeling it is more of a bug with componentDidCatch than it is with act, but maybe not.

const ThrowingComponent = () => {
  throw new Error('its a broken component')
}

class ErrorBoundary extends Component {
  componentDidCatch(error) {}
  render() {
    return this.props.children
  }
}

test('act', () => {
  jest.spyOn(console, 'error').mockImplementation(() => {})
  act(() => {
    const target = document.createElement('div')
    render(
      <ErrorBoundary>
        <ThrowingComponent />
      </ErrorBoundary>,
      target,
    )
  })
})

In React, this passes, in Preact, it doesn’t. Somehow the error is escaping past the componentDidCatch and up into the test, causing the test to fail. Any idea why?

It isn’t because of act. The 2nd test in each file in the repro repo doesn’t use act, and you can still see the issue (the uncaught promise error in the console). I think act is just making the issue more visible by synchronously causing the error to show itself.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
JoviDeCroockcommented, Aug 20, 2019

Still works though

	it.only('act', () => {
		let spy = sinon.spy();
		const ThrowingComponent = () => {
			throw new Error('Fatal');
		};

		class ErrorBoundary extends Component {
			componentDidCatch(error) {
				spy();
				this.setState({ error });
			}
			render() {
				return this.state.error ? 'error' : this.props.children;
			}
		}

		act(() => {
			render(
				<ErrorBoundary>
					<ThrowingComponent />
				</ErrorBoundary>,
				scratch,
			);
		});

		expect(spy).to.be.calledOnce;
		expect(scratch.innerHTML).to.equal('error');
	});
1reaction
calebebycommented, Aug 17, 2019

@JoviDeCroock your test passes because there isn’t anything that throws 😕

ThrowingComponent renders undefined

Read more comments on GitHub >

github_iconTop Results From Across the Web

Error Boundaries - React
To solve this problem for React users, React 16 introduces a new concept of an “error boundary”. ... Use componentDidCatch() to log error...
Read more >
Render Sub-component Error in React.js using Error Boundaries
Try-catch should be used to handle any potential issues that can occur due to invalid input/data, connection issues or bad server response, etc....
Read more >
Handling JavaScript errors in React with error boundaries
Use error boundaries in React components to handle JavaScript errors, act on them, and display a fallback user interface.
Read more >
Why is this component being rendered after throwing an error?
I'm currently following along with the React JS documentation and I've encountered an issue with the error boundaries not working as expected. I ......
Read more >
Test a componentDidCatch ErrorBoundary component in React
How to test a React componentDidCatch lifecycle method.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found