-
Notifications
You must be signed in to change notification settings - Fork 67
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Error boundary catches errors of child components #101
Comments
I understand, would you expect the error to be bubbled up if it isn't the one about missing DOM node? That'd be easy to accomplish by rethrowing it for that case. |
@Rendez Yeah, I think that would be a good solution, thank you for the fast response and the PR! 🎉🎉🎉 On the other hand, I'm not really sure why you brought in the error boundary, do you plan to handle more errors in the future? Otherwise maybe it could even be removed again? 🤔 |
Good question, let me give you a little context... Our query components and async components in general render loading states, e.g: <Observer onChange={...}>
<Query ...>
{null} // while loading
</Query>
</Observer> Often this loading state isn't a DOM node but they are Up until 1.0.5 we didn't throw but instead of just called the error reporter, and we saw a new error in production (our custom reporter). However, our error was missing the And this is the story of how we ended up with error boundaries on >=1.1.0. By the way, the reported errors will still appear in the console, whether you config the If you feel this is too protective from the library, then I am interested to know if you'd prefer to have two exports: one guarded observer and one raw one? |
🎉 This issue has been resolved in version 1.1.2 🎉 The release is available on: Your semantic-release bot 📦🚀 |
I experimented with the new version for a bit, but I could not manage to have the error propagated to our error boundary. I'm not sure what the reason is. Previously ( We display a crash message to the user and hide the faulty part of the page, since it is likely that the error will just happen again on re-mount. That's why we can not just call it a day and have What is confusing to me is the React docs on error boundaries do not mention re-throwing errors, or how a library component would use an error boundary without affecting unrelated children. I also did a bit of research and could not find anyone else doing something like this. So I think it is a bit unexpected that a library component introduces an error boundary. I decided to work around the error boundary of the intersection observer by doing:
I will discuss my workaround with the team and see how it works in production. If you would find a way to add the |
That is very strange, I added a test case specifically to prove that the parent error boundary would receive the propagated error. Can you confirm that at least it tries to re-render the component? I didn't try this into production though, but my guess (if the re-render happens for you too) is that the production build doesn't re-throw then, which would be a bit discouraging as that's the point of "re-throwing". After you give me some more feedback, I think I will cut a release where the default export does no include an error boundary, and perhaps even remove it |
Okay, super strange: after comparing your test case and then our code and debugging a bit more, I found the reason is apparently that we throw the error in a state update. To test our error boundaries, Sentry integration etc. we have a button in a debugging component. And like in the code I posted above a In both cases it re-renders the component (re-mounts it even I think, because some internal state is reset) so I guess this is really an edge-case and can be ignored? On the other hand, since we did not see any missing node errors before, I think we could still got with the version without the error boundary 🤔 |
That makes sense, error boundaries only catch errors during render. That is within render, cDM, cDU and constructor (I think). The re-mount happens simply because the error boundary we create simply re-renders the passed That said, you're right: I tried your example above (throwing in setState) and what's happening is, the error doesn't get bubbled up because on a re-render there is no following onClick trigger. It has to be a render error for it to be re-thrown automatically. That tells me this is a brittle mechanism and we shouldn't be catching anything in the library. It's unfortunate, but all we can do is to throw our custom error with a better message (back to the original idea). I'll cut a release without error boundaries as soon as I can. Thanks a lot for your collaboration on this! |
@Rendez Hey, thanks again for fixing this! Since we have this running in production for some time, I think it works perfectly. We actually have a "enterprise wrapper component" around the library which always inserts a |
That is a great way to use this. Thank you! |
Expected behavior
An error thrown by a child of the intersection observer should end up in the user deifned error boundary that was placed outside of the intersection observer.
Current behavior
The intersection observer catches all errors, istead of only handling a missing DOM node situation.
Steps to reproduce
Render an app like this:
You will find the
console.log('I am not called!');
is not called.Context (environment)
The text was updated successfully, but these errors were encountered: