-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
[Bug]: Client-only errors are not handled correctly on initial load. (Infinite loop!) #1678
Comments
In my case, the initial bug that caused this was having a reference to |
@dvargas92495 Glad you fixed it. But unfortunately fixing the error doesn't fix the error handling. What if it was your customer who found the bug? |
Right I agree completely. Just wanted to mention it in case anyone else run into something similar and have a hard time debuggine because of the infinite loop nature of the issue |
This happened to me when I was using a value imported from a Took me a long time to figure out since the tab would log around 300k errors per second and filled up the RAM so I had to binary search the code to find the crashing line by commenting out things and then killing the chrome tab on every reload that the error was still active. Example code: import { MyEnum } from "some_api.server";
export const loader = () => ({value: MyEnum.Foo });
export default function MyPage() {
const { value } = useLoaderFunction();
if (value == MyEnum.Foo) { // <-- Crash here; MyEnum is undefined since the import was stripped away in client bundle.
return "Foo!";
} else {
return "Other";
}
} |
Same issue here with a missing environment variable in a route component. They're hard to debug as the debugger is bricked along with the tab/browser as soon as the page starts running. What does help with debugging is to enable "Pause on exeptions" (both FF as well as Chrome have such an option), which will give you control over the execution before it all freezes up. As pointed out this seems like a bad usability issue if it occurs for users Running remix 1.11.1 on node 16 |
This happened to me as well. I removed the ErrorBoundary and it stopped looping infinitely, and showed me the error. This was caused by me attempting to destructure something that was undefined. Remix 1.13.0, node 19.6.1 |
@wub what version of react are you using? After some further debugging noticed I could only reproduce this on react 17 |
Hey @gerbyzation I got this on React 18.2.0 |
@wub Would you be able to make a small repro that you can share? |
I spent a good part of a day trying to figure this out, and it seems that this issue happens if you dont use the full html document like the docs suggest, and possibly made worse when the root is a fragment. I could recreate this consistently like this:
If you remove either the You can recreate by forcing an error on the client side by placing a useEffect that will fail inside of a route component:
I definitely suggest following the docs, and testing if you can still recreate this if you use the sample error boundary from the docs. |
This is a tricky one. I've dug a bit more into this and can still reproduce when mounting in a The error itself which causes the duplicate markup gets deep into the weeds of react reconciliation code but it appears the issue is not that it doesn't try to delete the invalid SSR markup - I can see that a given fiber gets marked for deletion ( The order of operations seems to be:
This may just be an invalid approach in this new world of hydrating the A.long those lines, I also noticed this reproduction is on React 17 and can confirm that upgrading to React 18 and using |
I managed to get a non-Remix reproduction together. It seems to be that React 17 is unable to handle hydration with an https://github.com/brophdawg11/react-ssr-hydration-loop I am going to close this out because this functionality of a root level |
Thanks @brophdawg11 for taking the time to get to the bottom of this, much appreciated. React 18 indeed seems to not have this issue. |
this issue is back in react 19 beta, seems to happen 100% of the time if you render an error boundary without html and body tags. once adding those, it happens some times, with the appendChild error, but not infinite looping at least. ~~edit: it is from a variable missing when error boundary is up in my own code, so it really is just obscuring the real problem in the code, once i was finally able to find this spot, it hasnt had the appendChild error. If there was some way to surface the real error instead of looping and having an internal error, this would help a lot~~ edit 2: i just had to trigger it more times to see appendChild come up again, it sometimes hits the error boundary correctly, other times it does not |
What version of Remix are you using?
1.1.3
What version of Node are you using? Minimum supported version is 14.
17.3.0
Steps to Reproduce
Expected Behavior
Renders ErrorBoundary.
Actual Behavior
ErrorBoundary mounting errors resulting in an infinite loop.
The server correctly renders the page with no error (SSR), but then there's the client-only error during hydration. I'm not sure what exactly happens next, but the whole thing ends up in an infinite loop of mounting ErrorBoundary, which itself throws an error, which again tries to mount the ErrorBoundary and so on.
EDIT:
If the client-only error happens in the root component (
App
), then it's handled correctly, so this only affects nested modules' components.The text was updated successfully, but these errors were encountered: