| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 |
|
| 11 | import { isRouteErrorResponse } from "../../router/utils.js";
|
| 12 | import { Scripts, useFrameworkContext } from "./components.js";
|
| 13 | import * as React$1 from "react";
|
| 14 |
|
| 15 | var RemixErrorBoundary = class extends React$1.Component {
|
| 16 | constructor(props) {
|
| 17 | super(props);
|
| 18 | this.state = {
|
| 19 | error: props.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: props.error || null,
|
| 29 | location: props.location
|
| 30 | };
|
| 31 | return {
|
| 32 | error: props.error || state.error,
|
| 33 | location: state.location
|
| 34 | };
|
| 35 | }
|
| 36 | render() {
|
| 37 | if (this.state.error) return React$1.createElement(RemixRootDefaultErrorBoundary, {
|
| 38 | error: this.state.error,
|
| 39 | isOutsideRemixApp: true
|
| 40 | });
|
| 41 | else return this.props.children;
|
| 42 | }
|
| 43 | };
|
| 44 | |
| 45 | |
| 46 |
|
| 47 | function RemixRootDefaultErrorBoundary({ error, isOutsideRemixApp }) {
|
| 48 | let { nonce } = useFrameworkContext();
|
| 49 | console.error(error);
|
| 50 | let heyDeveloper = React$1.createElement("script", {
|
| 51 | nonce,
|
| 52 | dangerouslySetInnerHTML: { __html: `
|
| 53 | console.log(
|
| 54 | "💿 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."
|
| 55 | );
|
| 56 | ` }
|
| 57 | });
|
| 58 | if (isRouteErrorResponse(error)) return React$1.createElement(BoundaryShell, { title: "Unhandled Thrown Response!" }, React$1.createElement("h1", { style: { fontSize: "24px" } }, error.status, " ", error.statusText), null);
|
| 59 | let errorInstance;
|
| 60 | if (error instanceof Error) errorInstance = error;
|
| 61 | else {
|
| 62 | let errorString = error == null ? "Unknown Error" : typeof error === "object" && "toString" in error ? error.toString() : JSON.stringify(error);
|
| 63 | errorInstance = new Error(errorString);
|
| 64 | }
|
| 65 | return React$1.createElement(BoundaryShell, {
|
| 66 | title: "Application Error!",
|
| 67 | isOutsideRemixApp
|
| 68 | }, React$1.createElement("h1", { style: { fontSize: "24px" } }, "Application Error"), React$1.createElement("pre", { style: {
|
| 69 | padding: "2rem",
|
| 70 | background: "hsla(10, 50%, 50%, 0.1)",
|
| 71 | color: "red",
|
| 72 | overflow: "auto"
|
| 73 | } }, errorInstance.stack), heyDeveloper);
|
| 74 | }
|
| 75 | function BoundaryShell({ title, renderScripts, isOutsideRemixApp, children }) {
|
| 76 | let { routeModules } = useFrameworkContext();
|
| 77 | if (routeModules.root?.Layout && !isOutsideRemixApp) return children;
|
| 78 | return React$1.createElement("html", { lang: "en" }, React$1.createElement("head", null, React$1.createElement("meta", { charSet: "utf-8" }), React$1.createElement("meta", {
|
| 79 | name: "viewport",
|
| 80 | content: "width=device-width,initial-scale=1,viewport-fit=cover"
|
| 81 | }), React$1.createElement("title", null, title)), React$1.createElement("body", null, React$1.createElement("main", { style: {
|
| 82 | fontFamily: "system-ui, sans-serif",
|
| 83 | padding: "2rem"
|
| 84 | } }, children, renderScripts ? React$1.createElement(Scripts, null) : null)));
|
| 85 | }
|
| 86 |
|
| 87 | export { BoundaryShell, RemixErrorBoundary, RemixRootDefaultErrorBoundary };
|