error.js 파일 규칙을 사용하면 중첩된 경로에서 런타임 오류를 우아하게 처리할 수 있습니다.
- React Error Boundary 내에 라우트 세그먼트와 해당 중첩된 하위 항목을 자동으로 래핑합니다.
- 파일 시스템 계층 구조를 사용하여 세분화를 조정하여 특정 세그먼트에 맞는 오류 UI를 생성합니다.
- 오류를 해당 세그먼트로 격리시키면서 나머지 앱은 정상적으로 동작합니다.
- 전체 페이지 새로고침 없이 오류로부터 복구를 시도하는 기능을 추가할 수 있습니다.
route segment 내에 error.js 파일을 추가하고 React 컴포넌트를 내보내어 오류 UI를 생성합니다.
/* app/dashboard/error.tsx */
'use client' // 에러 컴포넌트는 클라이언트 컴포넌트로 만들어야합니다.
import { useEffect } from 'react'
export default function Error({
error,
reset,
}: {
error: Error
reset: () => void
}) {
useEffect(() => {
// Log the error to an error reporting service
console.error(error)
}, [error])
return (
<div>
<h2>Something went wrong!</h2>
<button
onClick={
// 세그먼트를 재 렌더링 하여 복구를 시도합니다.
() => reset()
}
>
Try again
</button>
</div>
)
}
error.js 작동 방식
- error.js 파일은 자동으로 중첩된 하위 세그먼트나 page.js 컴포넌트를 감싸는 React Error Boundary를 생성합니다.
- error.js 파일에서 내보내는 React 컴포넌트는 fallback(대체) 컴포넌트로 사용됩니다.
- 에러가 에러 바운더리 내에서 발생하면 에러는 포함되고 fallback(대체) 컴포넌트가 렌더링됩니다.
- fallback 에러 컴포넌트가 활성화되면 에러 바운더리 밖의 레이아웃은 상태를 유지하고 상호작용할 수 있으며, 에러 컴포넌트에서 에러 복구 기능을 표시할 수 있습니다.
에러 복구 방법
오류의 원인은 때로는 일시적일 수 있습니다. 이러한 경우에는 간단히 다시 시도하면 문제가 해결될 수 있습니다.
오류 컴포넌트는 reset() 함수를 사용하여 사용자가 오류에서 복구를 시도하도록 유도할 수 있습니다. 이 함수가 실행되면 Error Boundary의 내용을 재 렌더링하려고 시도합니다. 성공하면 에러 컴포넌트가 재 렌더링된 결과로 대체됩니다.
Error .js파일이 중첩된 경우 작동 되는 방식
특수 파일을 통해 생성된 React 컴포넌트는 특정 중첩 계층 구조로 렌더링됩니다.
예를 들어, 두 개의 세그먼트가 모두 layout.js 및 error.js 파일을 포함하는 중첩 경로는 다음과 같은 단순화된 컴포넌트 계층 구조로 렌더링됩니다:
중첩된 컴포넌트 계층 구조는 중첩된 경로에서 error.js 파일의 동작에 영향을 미칩니다:
- 에러는 가장 가까운 부모 에러 바운더리로 전달됩니다. 즉, error.js 파일은 모든 중첩된 하위 세그먼트의 에러를 처리합니다. route의 중첩된 폴더의 다른 수준에 error.js 파일을 배치함으로써 더 세분화된 오류 UI를 구현할 수 있습니다.
- 에러 바운더리 컴포넌트는 그림 처럼 레이아웃 컴포넌트에 안에 생성되므로 동일한 세그먼트의 layout.js에서 발생하는 에러를 처리하지 않습니다.
루트 레이아웃의 에러 처리
루트 app/error.js 바운더리는 루트 app/layout.js 또는 app/template.js 컴포넌트에서 발생하는 에러를 처리하지 않습니다.
이러한 루트 컴포넌트에서 에러를 명시적으로 처리하려면 루트 app 디렉토리에 위치한 app/global-error.js라는 error.js의 변형을 사용하세요.
루트 error.js와 달리 global-error.js 에러 바운더리는 전체 애플리케이션을 감싸며, fallback 컴포넌트는 활성화될 때 루트 레이아웃을 대체합니다. 이로 인해 global-error.js는 자체적으로 <html> 및 <body> 태그를 정의해야 합니다.
global-error.js는 가장 세분화되지 않은 오류 UI로, 전체 애플리케이션에 대한 "catch-all" 에러 처리로 간주될 수 있습니다. 일반적으로 루트 컴포넌트는 덜 동적이므로 자주 트리거되지 않을 것입니다. 또한 다른 error.js 바운더리가 대부분의 에러를 처리할 것입니다.
global-error.js가 정의되었더라도 전역적으로 공유되는 UI 및 브랜딩이 포함된 루트 레이아웃 내에서 렌더링될 fallback 컴포넌트가 있는 root error.js를 정의하는 것이 권장됩니다.
/* app/global-error.tsx */
'use client'
export default function GlobalError({
error,
reset,
}: {
error: Error
reset: () => void
}) {
return (
<html>
<body>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</body>
</html>
)
}
서버 에러 처리
데이터 가져오기 중이거나 서버 컴포넌트 내에서 에러가 발생하면 Next.js는 해당 Error 객체를 가장 가까운 error.js 파일로 error prop으로 전달합니다.
next dev를 실행할 때, 해당 에러는 Server Component에서 클라이언트 error.js로 직렬화되어 전달됩니다. 제품 환경에서 next start를 실행할 때 보안을 위해, 일반적인 에러 메시지와 에러 메시지의 해시인 .digest가 error로 전달됩니다. 이 해시는 서버 로그와 대응하는 데 사용할 수 있습니다.
원본
'기억보단 기록을 > Next JS (App Router)' 카테고리의 다른 글
[NextJS 13] Routing - Intercepting Routes(라우트 가로채기) (0) | 2023.06.12 |
---|---|
[NextJS 13] Routing - Parallel Routes (병렬 라우트) (0) | 2023.06.12 |
[NextJS 13] Routing - Loading UI and Streaming (0) | 2023.06.07 |
[NextJS 13] Routing - Dynamic Routes (0) | 2023.06.06 |
[NextJS 13] Routing - Route Groups (0) | 2023.06.04 |