πŸ“š Reference


πŸ“œΒ Chapter


notFound

Suspense

ErrorBoundary

β€£

Route Handlers

next/cache

β€£

β€£

Error


μœ„μΉ˜ 400 처리(μž…λ ₯ 검증 μ‹€νŒ¨ λ“±) 500 처리(μ˜ˆμƒ λͺ»ν•œ μ˜ˆμ™Έ) UI ν‘œμ‹œ
Route Handler app/api/**/route.ts NextResponse.json(..., { status: 400/422 }) NextResponse.json(..., { status: 500 }) (λ˜λŠ” throw ν›„ catch) JSON(λ˜λŠ” 파일/슀트림)
Page/Server Component app/**/page.tsx νŽ˜μ΄μ§€ μƒνƒœλ‘œ β€œμž˜λͺ»λœ μš”μ²­β€ μ•ˆλ‚΄(μƒνƒœμ½”λ“œ 직접 μ§€μ • 어렀움) μ˜ˆμ™Έλ₯Ό throw β†’ ν•΄λ‹Ή μ„Έκ·Έλ¨ΌνŠΈμ˜ error.tsx둜 이동(응닡 500) error.tsx
Server Action "use server" κ°’ λ°˜ν™˜μœΌλ‘œ 폼 내뢀에 μ—λŸ¬ ν‘œμ‹œ(μƒνƒœμ½”λ“œ μ œμ–΄ X) throw ν•˜λ©΄ 500 + error.tsx 폼 μ—λŸ¬ λ©”μ‹œμ§€ or error.tsx
404 (특수) notFound() 호좜 β€” not-found.tsx (응닡 404)
Middleware middleware.ts κ°„λ‹¨ν•œ κ·œμΉ™ 차단 μ‹œ new NextResponse("...", { status: 400 }) β€” ν…μŠ€νŠΈ/λ¦¬λ‹€μ΄λ ‰νŠΈ

Route Handler: 400/500


// app/api/users/route.ts
import { NextResponse } from "next/server";

export async function POST(req: Request) {
  try {
    const body = await req.json();

    // μž…λ ₯ 검증 μ‹€νŒ¨ β†’ 400 λ˜λŠ” 422
    if (!body.email) {
      return NextResponse.json(
        { error: "email is required" },
        { status: 400 } // 422도 자주 μ‚¬μš©
      );
    }

    // ...λΉ„μ¦ˆλ‹ˆμŠ€ 둜직...
    return NextResponse.json({ ok: true }, { status: 201 });
  } catch (err) {
    console.error("POST /api/users error:", err);
    return NextResponse.json(
      { error: "Internal Server Error" },
      { status: 500 }
    );
  }
}

Page/Server Component: 404, 500 처리