In my Hello.jsx
component I'm calling an API which could fail. Here a fake API is called loader
:
import React, { useEffect } from "react";
export const Hello = () => {
const loader = async () => {
return Promise.reject("API error.");
};
useEffect(() => {
const load = async () => {
await loader();
};
load();
}, []);
return <h1>Hello World!</h1>;
};
Problem is that the ErrorBoundary
component (not displayed here) should print a red message but it doesn't. Error is not "catched". If I throw
normally, not inside an async function, it shows the red text "Something went wrong!". Any clue?
<div>
<ErrorBoundary>
<Hello />
</ErrorBoundary>
</div>
The function passed to useEffect is completing successfully. It defines a function, then successfully calls the function. The effect function returns undefined
normally, so there is nothing for the error boundary to catch.
Error boundaries do not catch all possible errors. Specifically, from the documentation on error boundaries:
Error boundaries do not catch errors for:
- Event handlers (learn more)
- Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks)
- Server side rendering
- Errors thrown in the error boundary itself (rather than its children)
If you want the error boundary to take action, then one option is to save the error in state and rethrow it from the component body. For example:
function MyComponent() {
const [error, setError] = useState(null);
if (error) {
throw error;
}
useEffect(() => {
// If loading fails, save the error in state so the component throws when it rerenders
load().catch(err => setError(err));
}, []);
return <div>...</div>
}