Skip to content
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

Deprecate CatchBoundary in favor of future.v2_errorBoundary #5718

Merged
merged 3 commits into from
Mar 9, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/three-cheetahs-lick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@remix-run/dev": patch
"@remix-run/react": patch
"@remix-run/server-runtime": patch
---

Deprecate `CatchBoundary` in favor of `future.v2_errorBoundary`
4 changes: 4 additions & 0 deletions docs/route/catch-boundary.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ title: CatchBoundary

# `CatchBoundary`

<docs-warning>The separation of `CatchBoundary` and `ErrorBoundary` has been deprecated and Remix v2 will use a singular `ErrorBoundary` for all thrown Responses and Errors. It is recommended that you opt-into the new behavior in Remix v1 via the `future.v2_errorBoundary` flag in your `remix.config.js` file. Please refer to the [ErrorBoundary (v2)][error-boundary-v2] docs for more information.</docs-warning>

A `CatchBoundary` is a React component that renders whenever an action or loader throws a `Response`.

**Note:** We use the word "catch" to represent the codepath taken when a `Response` type is thrown; you thought about bailing from the "happy path". This is different from an uncaught error you did not expect to occur.
Expand All @@ -29,3 +31,5 @@ export function CatchBoundary() {
);
}
```

[error-boundary-v2]: ./error-boundary-v2
11 changes: 11 additions & 0 deletions docs/route/error-boundary-v2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: ErrorBoundary (v2)
---

# `ErrorBoundary (v2)`

<docs-info>You can opt into the Remix v2 `ErrorBoundary` behavior via the `future.v2_errorBoundary` flag in your `remix.config.js`</docs-info>

If you export an `ErrorBoundary` component from your route module, it will be used as the React Router [`errorElement`][rr-error-element] and will render if you throw from a loader/action or if React throws during rendering your Route component.

[rr-error-element]: https://reactrouter.com/route/error-element
3 changes: 3 additions & 0 deletions docs/route/error-boundary.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ title: ErrorBoundary

# `ErrorBoundary`

<docs-warning>The separation of `CatchBoundary` and `ErrorBoundary` has been deprecated and Remix v2 will use a singular `ErrorBoundary` for all thrown Responses and Errors. It is recommended that you opt-into the new behavior in Remix v1 via the `future.v2_errorBoundary` flag in your `remix.config.js` file. Please refer to the [ErrorBoundary (v2)][error-boundary-v2] docs for more information.</docs-warning>

An `ErrorBoundary` is a React component that renders whenever there is an error anywhere on the route, either during rendering or during data loading.

**Note:** We use the word "error" to mean an uncaught exception; something you didn't anticipate happening. This is different from other types of "errors" that you are able to recover from easily, for example a 404 error where you can still show something in the user interface to indicate you weren't able to find some data.
Expand All @@ -26,3 +28,4 @@ export function ErrorBoundary({ error }) {
```

[error-boundaries]: https://reactjs.org/docs/error-boundaries.html
[error-boundary-v2]: ./error-boundary-v2
12 changes: 12 additions & 0 deletions packages/remix-dev/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,10 @@ export async function readConfig(
}
}

if (!appConfig.future?.v2_errorBoundary) {
warnOnce(errorBoundaryWarning, "v2_errorBoundary");
}

if (appConfig.serverBuildTarget) {
warnOnce(serverBuildTargetWarning, "v2_serverBuildTarget");
}
Expand Down Expand Up @@ -734,3 +738,11 @@ let listFormat = new Intl.ListFormat("en", {
export let serverBuildTargetWarning = `⚠️ DEPRECATED: The "serverBuildTarget" config option is deprecated. Use a combination of "publicPath", "serverBuildPath", "serverConditions", "serverDependenciesToBundle", "serverMainFields", "serverMinify", "serverModuleFormat" and/or "serverPlatform" instead.`;

export let flatRoutesWarning = `⚠️ DEPRECATED: The old nested folders route convention has been deprecated in favor of "flat routes". Please enable the new routing convention via the \`future.v2_routeConvention\` flag in your \`remix.config.js\` file. For more information, please see https://remix.run/docs/en/main/file-conventions/route-files-v2.`;

export const errorBoundaryWarning =
"⚠️ DEPRECATED: The separation of `CatchBoundary` and `ErrorBoundary` has " +
"been deprecated and Remix v2 will use a singular `ErrorBoundary` for " +
"all thrown values (`Response` and `Error`). Please migrate to the new " +
"behavior in Remix v1 via the `future.v2_errorBoundary` flag in your " +
"`remix.config.js` file. For more information, see " +
"https://remix.run/docs/route/error-boundary-v2";
13 changes: 13 additions & 0 deletions packages/remix-react/browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { deserializeErrors } from "./errors";
import type { RouteModules } from "./routeModules";
import { createClientRoutes } from "./routes";
import { warnOnce } from "./warnings";

/* eslint-disable prefer-let/prefer-let */
declare global {
Expand Down Expand Up @@ -138,6 +139,18 @@ if (import.meta && import.meta.hot) {
*/
export function RemixBrowser(_props: RemixBrowserProps): ReactElement {
if (!router) {
if (!window.__remixContext.future.v2_errorBoundary) {
warnOnce(
false,
"⚠️ DEPRECATED: The separation of `CatchBoundary` and `ErrorBoundary` has " +
"been deprecated and Remix v2 will use a singular `ErrorBoundary` for " +
"all thrown values (`Response` and `Error`). Please migrate to the new " +
"behavior in Remix v1 via the `future.v2_errorBoundary` flag in your " +
"`remix.config.js` file. For more information, see " +
"https://remix.run/docs/route/error-boundary-v2"
);
}

let routes = createClientRoutes(
window.__remixManifest.routes,
window.__remixRouteModules,
Expand Down
2 changes: 2 additions & 0 deletions packages/remix-react/errorBoundaries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ let RemixCatchContext = React.createContext<ThrownResponse | undefined>(
/**
* Returns the status code and thrown response data.
*
* @deprecated Please enable the v2_errorBoundary flag
*
* @see https://remix.run/route/catch-boundary
*/
export function useCatch<
Expand Down
4 changes: 4 additions & 0 deletions packages/remix-react/routeModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,17 @@ export interface RouteModule {
/**
* A React component that is rendered when the server throws a Response.
*
* @deprecated Please enable the v2_errorBoundary flag
*
* @see https://remix.run/route/catch-boundary
*/
export type CatchBoundaryComponent = ComponentType<{}>;

/**
* A React component that is rendered when there is an error on a route.
*
* @deprecated Please enable the v2_errorBoundary flag
*
* @see https://remix.run/route/error-boundary
*/
export type ErrorBoundaryComponent = ComponentType<{ error: Error }>;
Expand Down
13 changes: 12 additions & 1 deletion packages/remix-server-runtime/routeModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,25 @@ export interface ActionFunction {

/**
* A React component that is rendered when the server throws a Response.
*
* @deprecated Please enable the v2_errorBoundary flag
*/
export type CatchBoundaryComponent = ComponentType;

/**
* A React component that is rendered when there is an error on a route.
*
* @deprecated Please enable the v2_errorBoundary flag
*/
export type ErrorBoundaryComponent = ComponentType<{ error: Error }>;

/**
* V2 version of the ErrorBoundary that eliminates the distinction between
* Error and Catch Boundaries and behaves like RR 6.4 errorElement and captures
* errors with useRouteError()
*/
export type V2_ErrorBoundaryComponent = ComponentType;

/**
* A function that returns HTTP headers to be used for a route. These headers
* will be merged with (and take precedence over) headers from parent routes.
Expand Down Expand Up @@ -224,7 +235,7 @@ export type RouteHandle = any;

export interface EntryRouteModule {
CatchBoundary?: CatchBoundaryComponent;
ErrorBoundary?: ErrorBoundaryComponent;
ErrorBoundary?: ErrorBoundaryComponent | V2_ErrorBoundaryComponent;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

default: RouteComponent;
handle?: RouteHandle;
links?: LinksFunction;
Expand Down