| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 |
|
| 11 | import { isRouteErrorResponse } from "../router/utils.js";
|
| 12 | import { useRouteError } from "../hooks.js";
|
| 13 | import React from "react";
|
| 14 |
|
| 15 | var RSCRouterGlobalErrorBoundary = class extends React.Component {
|
| 16 | constructor(props) {
|
| 17 | super(props);
|
| 18 | this.state = {
|
| 19 | error: null,
|
| 20 | location: props.location
|
| 21 | };
|
| 22 | }
|
| 23 | static getDerivedStateFromError(error) {
|
| 24 | return { error };
|
| 25 | }
|
| 26 | static getDerivedStateFromProps(props, state) {
|
| 27 | if (state.location !== props.location) return {
|
| 28 | error: null,
|
| 29 | location: props.location
|
| 30 | };
|
| 31 | return {
|
| 32 | error: state.error,
|
| 33 | location: state.location
|
| 34 | };
|
| 35 | }
|
| 36 | render() {
|
| 37 | if (this.state.error) return React.createElement(RSCDefaultRootErrorBoundaryImpl, {
|
| 38 | error: this.state.error,
|
| 39 | renderAppShell: true
|
| 40 | });
|
| 41 | else return this.props.children;
|
| 42 | }
|
| 43 | };
|
| 44 | function ErrorWrapper({ renderAppShell, title, children }) {
|
| 45 | if (!renderAppShell) return children;
|
| 46 | return React.createElement("html", { lang: "en" }, React.createElement("head", null, React.createElement("meta", { charSet: "utf-8" }), React.createElement("meta", {
|
| 47 | name: "viewport",
|
| 48 | content: "width=device-width,initial-scale=1,viewport-fit=cover"
|
| 49 | }), React.createElement("title", null, title)), React.createElement("body", null, React.createElement("main", { style: {
|
| 50 | fontFamily: "system-ui, sans-serif",
|
| 51 | padding: "2rem"
|
| 52 | } }, children)));
|
| 53 | }
|
| 54 | function RSCDefaultRootErrorBoundaryImpl({ error, renderAppShell }) {
|
| 55 | console.error(error);
|
| 56 | let heyDeveloper = React.createElement("script", { dangerouslySetInnerHTML: { __html: `
|
| 57 | console.log(
|
| 58 | "💿 Hey developer 👋. You can provide a way better UX than this when your app throws errors. Check out https://reactrouter.com/how-to/error-boundary for more information."
|
| 59 | );
|
| 60 | ` } });
|
| 61 | if (isRouteErrorResponse(error)) return React.createElement(ErrorWrapper, {
|
| 62 | renderAppShell,
|
| 63 | title: "Unhandled Thrown Response!"
|
| 64 | }, React.createElement("h1", { style: { fontSize: "24px" } }, error.status, " ", error.statusText), null);
|
| 65 | let errorInstance;
|
| 66 | if (error instanceof Error) errorInstance = error;
|
| 67 | else {
|
| 68 | let errorString = error == null ? "Unknown Error" : typeof error === "object" && "toString" in error ? error.toString() : JSON.stringify(error);
|
| 69 | errorInstance = new Error(errorString);
|
| 70 | }
|
| 71 | return React.createElement(ErrorWrapper, {
|
| 72 | renderAppShell,
|
| 73 | title: "Application Error!"
|
| 74 | }, React.createElement("h1", { style: { fontSize: "24px" } }, "Application Error"), React.createElement("pre", { style: {
|
| 75 | padding: "2rem",
|
| 76 | background: "hsla(10, 50%, 50%, 0.1)",
|
| 77 | color: "red",
|
| 78 | overflow: "auto"
|
| 79 | } }, errorInstance.stack), heyDeveloper);
|
| 80 | }
|
| 81 | function RSCDefaultRootErrorBoundary({ hasRootLayout }) {
|
| 82 | let error = useRouteError();
|
| 83 | if (hasRootLayout === void 0) throw new Error("Missing 'hasRootLayout' prop");
|
| 84 | return React.createElement(RSCDefaultRootErrorBoundaryImpl, {
|
| 85 | renderAppShell: !hasRootLayout,
|
| 86 | error
|
| 87 | });
|
| 88 | }
|
| 89 |
|
| 90 | export { RSCDefaultRootErrorBoundary, RSCRouterGlobalErrorBoundary };
|