오류는 두 가지 범주로 나눌 수 있다. expected Errors와 uncaught exceptions가 있다.
이 페이지에서는 Next.js 애플리케이션에서 이러한 오류를 처리하는 방법을 안내한다.
예상된 오류는 서버 측 폼 유효성 검사 오류나 요청 실패와 같이 애플리케이션의 정상적인 작동 중에 발생할 수 있는 오류다.
이러한 오류는 명시적으로 처리하여 클라이언트로 반환해야 한다.
Server Function에서 예상된 오류를 처리하기 위해 useActionState 훅을 사용할 수 있다.
이러한 오류에 대해서는 try / catch 블록을 사용하고 오류를 throw하는 것을 피해야 한다.
대신, 예상된 오류를 반환값으로 모델링해보자.
app/actions.ts
'use server'
export async function createPost(prevState: any, formData: FormData) {
const title = formData.get('title')
const content = formData.get('content')
const res = await fetch('<https://api.vercel.app/posts>', {
method: 'POST',
body: { title, content },
})
const json = await res.json()
if (!res.ok) {
return { message: 'Failed to create post' }
}
}
action을 useActionState 훅에 전달하고, 반환된 state를 사용하여 오류 메시지를 표시할 수 있다.
app/ui/form.tsx
'use client'
import { useActionState } from 'react'
import { createPost } from '@/app/actions'
const initialState = {
message: '',
}
export function Form() {
const [state, formAction, pending] = useActionState(createPost, initialState)
return (
<form action={formAction}>
<label htmlFor="title">Title</label>
<input type="text" id="title" name="title" required />
<label htmlFor="content">Content</label>
<textarea id="content" name="content" required />
{state?.message && <p aria-live="polite">{state.message}</p>}
<button disabled={pending}>Create Post</button>
</form>
)
}
Server Component 내에서 데이터를 페칭할 때, respose를 이용하여 조건부로 오류 메시지를 렌더링하거나 redirect할 수 있다.
app/page.tsx
export default async function Page() {
const res = await fetch(`https://...`)
const data = await res.json()
if (!res.ok) {
return 'There was an error.'
}
return '...'
}
라우트 세그먼트 내에서 notFound 함수를 호출할 수 있으며, not-found.js 파일을 사용하여 404 UI를 표시할 수 있다.
app/blog/[slug]/page.tsx
import { getPostBySlug } from '@/lib/posts'
export default async function Page({ params }: { params: { slug: string } }) {
const { slug } = await params
const post = getPostBySlug(slug)
if (!post) {
notFound()
}
return <div>{post.title}</div>
}
app/blog/[slug]not-found.tsx
export default function NotFound() {
return <div>404 - Page Not Found</div>
}