Skip to content

Commit e6814d5

Browse files
authored
Properly handle falsy error values in ErrorBoundary's (#11071)
1 parent dc7833c commit e6814d5

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

.changeset/handle-falsy-errors.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"react-router": patch
3+
---
4+
5+
Properly handle falsy error values in ErrorBoundary's

packages/react-router/__tests__/data-memory-router-test.tsx

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2014,6 +2014,50 @@ describe("createMemoryRouter", () => {
20142014
}
20152015
});
20162016

2017+
it("handles a `null` render-error", async () => {
2018+
let router = createMemoryRouter([
2019+
{
2020+
path: "/",
2021+
Component() {
2022+
throw null;
2023+
},
2024+
ErrorBoundary() {
2025+
return <pre>{useRouteError() === null ? "Yes" : "No"}</pre>;
2026+
},
2027+
},
2028+
]);
2029+
let { container } = render(<RouterProvider router={router} />);
2030+
2031+
await waitFor(() => screen.getByText("Yes"));
2032+
expect(getHtml(container)).toMatch("Yes");
2033+
});
2034+
2035+
it("handles a `null` render-error from a defer() call", async () => {
2036+
let router = createMemoryRouter([
2037+
{
2038+
path: "/",
2039+
loader() {
2040+
return defer({ lazy: Promise.reject(null) });
2041+
},
2042+
Component() {
2043+
let data = useLoaderData() as { lazy: Promise<unknown> };
2044+
return (
2045+
<React.Suspense>
2046+
<Await resolve={data.lazy}>No</Await>
2047+
</React.Suspense>
2048+
);
2049+
},
2050+
ErrorBoundary() {
2051+
return <pre>{useRouteError() === null ? "Yes" : "No"}</pre>;
2052+
},
2053+
},
2054+
]);
2055+
let { container } = render(<RouterProvider router={router} />);
2056+
2057+
await waitFor(() => screen.getByText("Yes"));
2058+
expect(getHtml(container)).toMatch("Yes");
2059+
});
2060+
20172061
it("handles back button routing away from a child error boundary", async () => {
20182062
let router = createMemoryRouter(
20192063
createRoutesFromElements(

packages/react-router/lib/hooks.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ export class RenderErrorBoundary extends React.Component<
600600
// this because the error provided from the app state may be cleared without
601601
// the location changing.
602602
return {
603-
error: props.error || state.error,
603+
error: props.error !== undefined ? props.error : state.error,
604604
location: state.location,
605605
revalidation: props.revalidation || state.revalidation,
606606
};
@@ -615,7 +615,7 @@ export class RenderErrorBoundary extends React.Component<
615615
}
616616

617617
render() {
618-
return this.state.error ? (
618+
return this.state.error !== undefined ? (
619619
<RouteContext.Provider value={this.props.routeContext}>
620620
<RouteErrorContext.Provider
621621
value={this.state.error}
@@ -891,7 +891,7 @@ export function useRouteError(): unknown {
891891

892892
// If this was a render error, we put it in a RouteError context inside
893893
// of RenderErrorBoundary
894-
if (error) {
894+
if (error !== undefined) {
895895
return error;
896896
}
897897

0 commit comments

Comments
 (0)