Fix 404 page crashing

This commit is contained in:
Kalle
2022-07-16 13:21:01 +03:00
parent 83d34353c2
commit 3bb09a64a3
5 changed files with 57 additions and 24 deletions

View File

@@ -27,15 +27,24 @@ export function Catcher() {
)}
</Main>
);
case 404:
return (
<Main>
<h2>Error {caught.status} - Page not found</h2>
<GetHelp />
</Main>
);
default:
return (
<Main>
<h2>Error {caught.status}</h2>
{caught.data ? (
<code>{JSON.stringify(caught.data, null, 2)}</code>
) : null}
<GetHelp />
</Main>
);
}
return (
<Main>
<h2>Error {caught.status}</h2>
{caught.data ? <code>{JSON.stringify(caught.data, null, 2)}</code> : null}
<GetHelp />
</Main>
);
}
function GetHelp() {

View File

@@ -1,4 +1,4 @@
import { Link, useLoaderData } from "@remix-run/react";
import { Link } from "@remix-run/react";
import type { RootLoaderData } from "~/root";
import { discordFullName } from "~/utils/strings";
import {
@@ -16,9 +16,11 @@ import { PatreonIcon } from "../icons/Patreon";
import { TwitterIcon } from "../icons/Twitter";
import { Image } from "../Image";
export function Footer() {
const data = useLoaderData<RootLoaderData>();
export function Footer({
patrons = [],
}: {
patrons?: RootLoaderData["patrons"];
}) {
return (
<footer className="layout__footer">
<div className="layout__footer__link-list">
@@ -71,7 +73,7 @@ export function Footer() {
<PatreonIcon className="layout__footer__social-icon patreon" />
</a>
</div>
{data.patrons.length > 0 ? (
{patrons.length > 0 ? (
<div>
<h4 className="layout__footer__patron-title">
Thanks to the patrons for the support
@@ -83,7 +85,7 @@ export function Footer() {
/>
</h4>
<ul className="layout__footer__patron-list">
{data.patrons.map((patron) => (
{patrons.map((patron) => (
<li key={patron.id}>
<Link to={userPage(patron.discordId)}>
{discordFullName(patron)}

View File

@@ -6,11 +6,14 @@ import navItems from "./nav-items.json";
import { useLocation } from "@remix-run/react";
import { Image } from "../Image";
import { Footer } from "./Footer";
import type { RootLoaderData } from "~/root";
export const Layout = React.memo(function Layout({
children,
patrons,
}: {
children: React.ReactNode;
patrons?: RootLoaderData["patrons"];
}) {
const location = useLocation();
const [menuOpen, setMenuOpen] = React.useState(false);
@@ -46,7 +49,7 @@ export const Layout = React.memo(function Layout({
</header>
<Menu expanded={menuOpen} closeMenu={() => setMenuOpen(false)} />
{children}
<Footer />
<Footer patrons={patrons} />
</div>
);
});

View File

@@ -1,10 +1,9 @@
import type {
LinksFunction,
LoaderFunction,
MetaFunction,
import {
json,
type LinksFunction,
type LoaderFunction,
type MetaFunction,
} from "@remix-run/node";
import { json } from "@remix-run/node";
import type { ShouldReloadFunction } from "@remix-run/react";
import {
Links,
LiveReload,
@@ -12,6 +11,8 @@ import {
Outlet,
Scripts,
ScrollRestoration,
useLoaderData,
type ShouldReloadFunction,
} from "@remix-run/react";
import * as React from "react";
import commonStyles from "~/styles/common.css";
@@ -66,7 +67,13 @@ export const loader: LoaderFunction = async ({ request }) => {
});
};
function Document({ children }: { children: React.ReactNode }) {
function Document({
children,
patrons,
}: {
children: React.ReactNode;
patrons?: RootLoaderData["patrons"];
}) {
return (
<html lang="en">
<head>
@@ -76,7 +83,7 @@ function Document({ children }: { children: React.ReactNode }) {
</head>
<body>
<React.StrictMode>
<Layout>{children}</Layout>
<Layout patrons={patrons}>{children}</Layout>
</React.StrictMode>
<ScrollRestoration />
<Scripts />
@@ -87,8 +94,12 @@ function Document({ children }: { children: React.ReactNode }) {
}
export default function App() {
// prop drilling patrons instead of using useLoaderData in the Footer directly because
// useLoaderData can't be used in CatchBoundary and Footer is rendered in it as well
const data = useLoaderData<RootLoaderData>();
return (
<Document>
<Document patrons={data.patrons}>
<Outlet />
</Document>
);

8
cypress/e2e/misc.cy.ts Normal file
View File

@@ -0,0 +1,8 @@
export {};
describe("404 page", () => {
it("should say 404 if accessing URL that doesn't exist", () => {
cy.visit("/plus/idonotexist", { failOnStatusCode: false });
cy.contains("404");
});
});