-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(react-server): client error boundary for server error (#211)
- Loading branch information
Showing
27 changed files
with
473 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
packages/react-server/examples/basic/src/routes/demo/waku_02/[pokemon]/error.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
"use client"; | ||
|
||
import type { ErrorRouteProps } from "@hiogawa/react-server/server"; | ||
|
||
export default function ErrorPage(props: ErrorRouteProps) { | ||
return <div>{props.serverError?.pokemonError || "Unknown error"}</div>; | ||
} |
13 changes: 13 additions & 0 deletions
13
packages/react-server/examples/basic/src/routes/demo/waku_02/[pokemon]/layout.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Link } from "@hiogawa/react-server/client"; | ||
import { type LayoutRouteProps } from "@hiogawa/react-server/server"; | ||
|
||
export default async function Layout(props: LayoutRouteProps) { | ||
return ( | ||
<div className="flex flex-col items-center gap-4 p-4"> | ||
<Link href="/demo/waku_02" className="antd-btn antd-btn-default px-2"> | ||
Home | ||
</Link> | ||
{props.children} | ||
</div> | ||
); | ||
} |
55 changes: 27 additions & 28 deletions
55
packages/react-server/examples/basic/src/routes/demo/waku_02/[pokemon]/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,41 @@ | ||
import { Link } from "@hiogawa/react-server/client"; | ||
import type { PageRouteProps } from "@hiogawa/react-server/server"; | ||
import { type PageRouteProps, createError } from "@hiogawa/react-server/server"; | ||
import { tinyassert } from "@hiogawa/utils"; | ||
import { fetchPokemons } from "../_utils"; | ||
|
||
// extend server error to include detail | ||
declare module "@hiogawa/react-server/server" { | ||
interface ReactServerErrorContext { | ||
pokemonError?: string; | ||
} | ||
} | ||
|
||
export default async function Page(props: PageRouteProps) { | ||
const pokemons = await fetchPokemons(); | ||
tinyassert("pokemon" in props.match.params); | ||
|
||
const slug = props.match.params["pokemon"]; | ||
const e = pokemons.find((e) => e.slug === slug); | ||
if (!e) { | ||
throw createError({ status: 404, pokemonError: `Not found : ${slug}` }); | ||
} | ||
|
||
return ( | ||
<div className="flex flex-col items-center gap-4 p-4"> | ||
<Link href="/demo/waku_02" className="antd-btn antd-btn-default px-2"> | ||
Home | ||
</Link> | ||
|
||
{/* TODO: not found error convention? */} | ||
{!e && <>Not Found : {slug}</>} | ||
|
||
{e && ( | ||
<div className="flex flex-col items-center"> | ||
<img | ||
src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${e.id}.png`} | ||
alt={e.slug} | ||
className="w-50 aspect-square" | ||
/> | ||
<div className="flex flex-col items-center gap-0.5 text-lg"> | ||
<span>{e.name.english}</span> | ||
<span>{e.name.japanese}</span> | ||
<span>Types: {e.type.join(", ")}</span> | ||
{Object.entries(e.base).map(([k, v]) => ( | ||
<div key={k}> | ||
{k}: {v} | ||
</div> | ||
))} | ||
<div className="flex flex-col items-center"> | ||
<img | ||
src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${e.id}.png`} | ||
alt={e.slug} | ||
className="w-50 aspect-square" | ||
/> | ||
<div className="flex flex-col items-center gap-0.5 text-lg"> | ||
<span>{e.name.english}</span> | ||
<span>{e.name.japanese}</span> | ||
<span>Types: {e.type.join(", ")}</span> | ||
{Object.entries(e.base).map(([k, v]) => ( | ||
<div key={k}> | ||
{k}: {v} | ||
</div> | ||
</div> | ||
)} | ||
))} | ||
</div> | ||
</div> | ||
); | ||
} |
20 changes: 20 additions & 0 deletions
20
packages/react-server/examples/basic/src/routes/demo/waku_02/_client.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
"use client"; | ||
|
||
import { __global } from "@hiogawa/react-server"; | ||
|
||
// TODO: server action + redirect | ||
export function SearchInput() { | ||
return ( | ||
<form | ||
onSubmit={(e) => { | ||
e.preventDefault(); | ||
const q = e.currentTarget["q"].value; | ||
if (typeof q === "string") { | ||
__global.history.push(`/demo/waku_02/${q.toLowerCase()}`); | ||
} | ||
}} | ||
> | ||
<input name="q" className="antd-input px-2" placeholder="Search..." /> | ||
</form> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
15 changes: 15 additions & 0 deletions
15
packages/react-server/examples/basic/src/routes/test/error.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
"use client"; | ||
|
||
import type { ErrorRouteProps } from "@hiogawa/react-server/server"; | ||
|
||
export default function ErrorPage(props: ErrorRouteProps) { | ||
return ( | ||
<div className="flex flex-col gap-2"> | ||
<h4>ErrorPage</h4> | ||
<div> | ||
server error:{" "} | ||
{props.serverError ? JSON.stringify(props.serverError) : "(N/A)"} | ||
</div> | ||
</div> | ||
); | ||
} |
10 changes: 10 additions & 0 deletions
10
packages/react-server/examples/basic/src/routes/test/error/browser/_client.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
"use client"; | ||
|
||
import React from "react"; | ||
|
||
export function ClinetPage() { | ||
React.useEffect(() => { | ||
throw new Error("boom!"); | ||
}, []); | ||
return <div>Error on Effect</div>; | ||
} |
5 changes: 5 additions & 0 deletions
5
packages/react-server/examples/basic/src/routes/test/error/browser/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { ClinetPage } from "./_client"; | ||
|
||
export default function Page() { | ||
return <ClinetPage />; | ||
} |
26 changes: 26 additions & 0 deletions
26
packages/react-server/examples/basic/src/routes/test/error/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { Link } from "@hiogawa/react-server/client"; | ||
|
||
export default async function Page() { | ||
return ( | ||
<div className="flex gap-2 p-2"> | ||
<Link | ||
className="antd-btn antd-btn-default px-2" | ||
href="/test/error/server?500" | ||
> | ||
Server 500 | ||
</Link> | ||
<Link | ||
className="antd-btn antd-btn-default px-2" | ||
href="/test/error/server?custom" | ||
> | ||
Server Custom | ||
</Link> | ||
<Link | ||
className="antd-btn antd-btn-default px-2" | ||
href="/test/error/browser" | ||
> | ||
Browser | ||
</Link> | ||
</div> | ||
); | ||
} |
15 changes: 15 additions & 0 deletions
15
packages/react-server/examples/basic/src/routes/test/error/server/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { type PageRouteProps, createError } from "@hiogawa/react-server/server"; | ||
|
||
declare module "@hiogawa/react-server/server" { | ||
interface ReactServerErrorContext { | ||
customMessage?: string; | ||
} | ||
} | ||
|
||
export default function Page(props: PageRouteProps) { | ||
const url = new URL(props.request.url); | ||
if (url.searchParams.has("custom")) { | ||
throw createError({ status: 403, customMessage: "hello" }); | ||
} | ||
throw new Error("boom!"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,7 @@ | ||
"use client"; | ||
|
||
export { createServerReference } from "./lib/shared"; | ||
export { | ||
ErrorBoundary, | ||
DefaultRootErrorPage, | ||
} from "./lib/components/error-boundary"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.