mirror of
https://github.com/fabro-sh/fabro.git
synced 2026-10-31 06:56:12 +00:00
Merge pull request #1077 from fabro-sh/codex/correct-404-error-page
Some checks are pending
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
Rust / Rustdoc (push) Waiting to run
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Process titles (musl) (push) Waiting to run
Rust / Sandbox providers (Docker) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
TypeScript / Typecheck (push) Waiting to run
TypeScript / Test (push) Waiting to run
TypeScript / Build (push) Waiting to run
Some checks are pending
Rust / Format (push) Waiting to run
Rust / Clippy (push) Waiting to run
Rust / Rustdoc (push) Waiting to run
Rust / Generated Docs (push) Waiting to run
Rust / Test (Linux) (push) Waiting to run
Rust / Process titles (musl) (push) Waiting to run
Rust / Sandbox providers (Docker) (push) Waiting to run
Rust / Test (macOS) (push) Waiting to run
TypeScript / Typecheck (push) Waiting to run
TypeScript / Test (push) Waiting to run
TypeScript / Build (push) Waiting to run
Show the correct 404 page for missing browser routes
This commit is contained in:
commit
0179502e5f
2 changed files with 79 additions and 2 deletions
76
apps/fabro-web/app/root.test.tsx
Normal file
76
apps/fabro-web/app/root.test.tsx
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import { describe, expect, test } from "bun:test";
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import { createMemoryRouter, RouterProvider, type RouteObject } from "react-router";
|
||||
|
||||
import { installRoutes } from "./install-router";
|
||||
import { routes } from "./router";
|
||||
|
||||
async function renderPage(routeObjects: RouteObject[], path: string, navigate = false) {
|
||||
const router = createMemoryRouter(routeObjects, {
|
||||
initialEntries: [navigate ? "/" : path],
|
||||
});
|
||||
try {
|
||||
if (navigate) await router.navigate(path);
|
||||
return renderToStaticMarkup(<RouterProvider router={router} />);
|
||||
} finally {
|
||||
router.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
describe("root error boundary", () => {
|
||||
for (const path of ["/some_random_route", "/runs/existing-run/billing"]) {
|
||||
for (const navigate of [false, true]) {
|
||||
test(`${path} displays 404 on ${navigate ? "navigation" : "initial load"}`, async () => {
|
||||
const html = await renderPage(routes, path, navigate);
|
||||
|
||||
expect(html).toContain(">404</p>");
|
||||
expect(html).toContain("Page not found");
|
||||
expect(html).not.toContain("Something went wrong");
|
||||
expect(html).toContain('href="/runs"');
|
||||
expect(html).toContain("Go back");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (const [name, root] of [["app", routes[0]], ["installer", installRoutes[0]]] as const) {
|
||||
async function renderFailure(error: unknown) {
|
||||
return renderPage([
|
||||
{
|
||||
...root,
|
||||
children: [{
|
||||
path: "failure",
|
||||
loader() { throw error; },
|
||||
Component: () => null,
|
||||
}],
|
||||
},
|
||||
], "/failure", true);
|
||||
}
|
||||
|
||||
test(`${name} displays a route's 404 response as page not found`, async () => {
|
||||
const html = await renderFailure(new Response(null, { status: 404 }));
|
||||
|
||||
expect(html).toContain(">404</p>");
|
||||
expect(html).toContain("Page not found");
|
||||
expect(html).not.toContain("Something went wrong");
|
||||
});
|
||||
|
||||
test.each([403, 500])(`${name} preserves a route's %i error response`, async (status) => {
|
||||
const statusText = status === 403 ? "Forbidden" : "Internal Server Error";
|
||||
const html = await renderFailure(new Response(null, { status, statusText }));
|
||||
|
||||
expect(html).toContain(`>${status}</p>`);
|
||||
expect(html).toContain(`${status} Error`);
|
||||
expect(html).toContain(statusText);
|
||||
expect(html).not.toContain("Page not found");
|
||||
});
|
||||
|
||||
test(`${name} keeps unexpected exceptions as 500 errors`, async () => {
|
||||
const html = await renderFailure(new Error("Unexpected route failure"));
|
||||
|
||||
expect(html).toContain(">500</p>");
|
||||
expect(html).toContain("Something went wrong");
|
||||
expect(html).toContain("Unexpected route failure");
|
||||
expect(html).not.toContain("Page not found");
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
import { isRouteErrorResponse, Outlet } from "react-router";
|
||||
import { isRouteErrorResponse, Outlet, useRouteError } from "react-router";
|
||||
|
||||
export default function Root() {
|
||||
return <Outlet />;
|
||||
}
|
||||
|
||||
export function ErrorBoundary({ error }: any) {
|
||||
export function ErrorBoundary() {
|
||||
const error = useRouteError();
|
||||
let status = 500;
|
||||
let heading = "Something went wrong";
|
||||
let message = "An unexpected error occurred. Please try again.";
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue