-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Can't catch all useGLTF errors with React Error Boundaries #3181
Comments
Here is my workaround code for now in case it is helpful for folks. Note: this isn't idiomatic React and probably causes other problems in some situations.
|
I'd need to see an example, but this sounds like a React bug which should be taken upstream. You can harden your workaround by continuing to throw a promise if passed to |
I think it's expected behavior of react error boundaries that they won't catch errors in async code – my understanding is that the error needs to happen in the React tree's render stack to catch it. Here's a repro (I deleted random info in the GLB file to simulate a bad network request) You'll see that even though there's an error boundary, the error thrown by Seems odd that I'd be the first person to find this so I could definitely be missing something... although you might only notice |
Okay, we're probably not catching errors thrown from promises. We don't intend for this tricky behavior to be possible. |
The way it happened in the wild was a valid URL but a network error on Poki (so not a 404 but not the full file returned either) happening once every thousand users or so. |
Looks like that's exactly the problem here. You can get the same broken behavior with below (where it skips the error boundary entirely), but not if you make import * as React from 'react'
import * as THREE from 'three'
import { createRoot } from 'react-dom/client'
import { ErrorBoundary } from 'react-error-boundary'
import { useLoader, Canvas } from '@react-three/fiber'
class ThrowableLoader extends THREE.Loader {
async load() {
throw 'test'
}
}
function Test() {
useLoader(ThrowableLoader, '')
}
createRoot(root).render(
<ErrorBoundary fallback={<div>Something went wrong</div>}>
<Canvas>
<Test />
</Canvas>
</ErrorBoundary>,
) |
@drcmda, we should take this upstream with suspend-react, but is this a known issue or pitfall with legacy Suspense? |
I've noticed that some useGLTF errors don't get caught by the error boundary (since react error boundaries only handle errors that impact the react tree).
If you cause the decoding to fail, by say deleting random bytes out of a glb file, something inside useGLTF will throw but not be caught by the error boundary. This just causes the app to crash and a blank canvas. I'm running into this on a high traffic site where a small percentage of network requests for my glb file get interrupted.
Any advice on how to handle cases like these?
The text was updated successfully, but these errors were encountered: