OPEN HYPER STEP
← 목록으로 (stack-analysis)
STACK-ANALYSIS · 20 / 90
stack-analysis
CHAPTER 20 / 90
읽기 약 2
FUNCTION

에러 바운더리 + 로딩 UI + 스트리밍 SSR


핵심 개념

error.tsx·not-found.tsx·loading.tsx·streaming — 견고한 사용자 경험.

본문

error.tsx (자동 Error Boundary)

TSX📋 코드 (43줄)
// app/posts/error.tsx
'use client';

import { useEffect } from 'react';

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  useEffect(() => {
    // Sentry 등에 보고
    console.error('Posts error:', error);
  }, [error]);

  return (
    <div className="error-container">
      <h2>문제가 발생했습니다</h2>
      <p>{error.message}</p>
      {error.digest && (
        <p style={{ fontSize: 12, color: '#999' }}>참조 ID: {error.digest}</p>
      )}
      <button onClick={() => reset()}>다시 시도</button>
    </div>
  );
}


// 글로벌 (root layout 에러)
// app/global-error.tsx
'use client';
export default function GlobalError({ error, reset }: { ... }) {
  return (
    <html>
      <body>
        <h1>심각한 오류</h1>
        <button onClick={reset}>재시도</button>
      </body>
    </html>
  );
}

not-found.tsx

TSX📋 코드 (22줄)
// app/posts/[slug]/page.tsx
import { notFound } from 'next/navigation';

export default async function Page({ params }: { params: { slug: string } }) {
  const post = await getPost(params.slug);
  if (!post) notFound();  // → not-found.tsx 렌더

  return <article>{post.content}</article>;
}


// app/posts/[slug]/not-found.tsx
import Link from 'next/link';

export default function NotFound() {
  return (
    <div>
      <h2>글을 찾을 수 없습니다</h2>
      <Link href="/posts">목록으로</Link>
    </div>
  );
}

loading.tsx + Suspense 조합

TSX📋 코드 (19줄)
// app/dashboard/loading.tsx — 페이지 전체 로딩
export default function Loading() {
  return <DashboardSkeleton />;
}


// app/dashboard/page.tsx — 부분 Suspense
import { Suspense } from 'react';

export default function Dashboard() {
  return (
    <>
      <Header />  {/* 빠른 부분 */}
      <Suspense fallback={<ChartSkeleton />}>
        <SlowChart />
      </Suspense>
    </>
  );
}

Streaming SSR — Suspense Boundaries

TSX📋 코드 (13줄)
// 페이지 응답 흐름:
// 1. <html><head>...</head><body>
// 2.   <Header />
// 3.   <ChartSkeleton />  ← 즉시 표시
// 4.   ... (데이터 fetch 중)
// 5.   <script>renderChart(data)</script>  ← 준비 시 교체
// 6. </body></html>


// 결과:
// - TTFB: 빠름 (즉시 시작)
// - LCP: 빠름 (Header + Skeleton)
// - 차트는 준비되면 자동 교체

React Error Boundary 패턴

TSX📋 코드 (15줄)
// 컴포넌트 단위 — react-error-boundary
import { ErrorBoundary } from 'react-error-boundary';

function FallbackComponent({ error, resetErrorBoundary }: any) {
  return (
    <div role="alert">
      <p>오류: {error.message}</p>
      <button onClick={resetErrorBoundary}>재시도</button>
    </div>
  );
}

<ErrorBoundary FallbackComponent={FallbackComponent}>
  <RiskyComponent />
</ErrorBoundary>

Sentry 통합

TYPESCRIPT📋 코드 (22줄)
// sentry.client.config.ts
import * as Sentry from '@sentry/nextjs';

Sentry.init({
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
  tracesSampleRate: 0.1,
  replaysSessionSampleRate: 0.0,
  replaysOnErrorSampleRate: 1.0,
});


// app/error.tsx에서 자동 호출
'use client';
import * as Sentry from '@sentry/nextjs';
import { useEffect } from 'react';

export default function Error({ error }: { error: Error }) {
  useEffect(() => {
    Sentry.captureException(error);
  }, [error]);
  return <div>오류 발생</div>;
}

다음 모듈

CH.21~26 "CSS·디자인 시스템" — Tailwind 심화.


AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude

무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6

내 코드의 에러 처리 부분을 분석해서
실전 분석 + 개선 우선순위를 알려줘.
ChatGPT

무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro

에러 처리 관련 인기 라이브러리/패턴 5개를
비교 분석해서 패턴 추출를 알려줘.
Gemini

무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro

내 프로젝트 전체에서 에러 처리
최적화 가능 위치를 보고해줘.
Grok

무료: Grok 4.1 / SuperGrok $30/mo

2026년 한국 프론트엔드 시장의
에러 처리 트렌드를 솔직히 알려줘.

⭐ 이것만 기억하세요
에러 바운더리 + 로딩 UI + 스트리밍 SSR 이 3가지만 확실히 잡으세요
1.error.tsx·not-found.tsx·loading.tsx 자동 처리 — Next.js App Router 표준
2.Streaming SSR = TTFB 빠름 + 점진 렌더 + Suspense Boundary로 세분
3.Sentry로 error.tsx 통합 — 프로덕션 에러 추적 표준


공유하기
진행도 20 / 90