Next.js(ver.13)/Routing
Error Handling
ecoEarth
2023. 8. 2. 04:04
Error Handling
error.js는 pgae.js와 같은 Nex.js의 파일컨벤션이다.
- Error컴포넌트는 반드시 'use client'로 Client Components화 시켜야 한다.
- 특정 segment에 특정 에러바운더리를 설정할 수 있다. -> segment별로 page.js가 있는 것처럼
- 전체 페이지를 다시 로드하지 않고 오류에서 복구를 시도하는 기능을 사용할 수 있다. -> reset() <- 별거 없다. 에러바운더리안에 래핑된 컴포넌트가 re-render된다.
- 에러바운더리에 설정한 fallback이 활성화되면 오류 경계 외의 레이아웃요소는 해당 state와 interactive UI를 유지하며 오류가 발생한 컴포넌트는 오류를 복구하는 기능을 표시할 수 있다. -> loading.js뿐만 아니라 error.js도 컴포넌트별로 다뤄지네
"use client"; // 에러 컴포넌트는 반드시 클라이언트 컴포넌트여야함!
import { useEffect } from "react";
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
useEffect(() => {
// 에러메시지 기록용
console.error(error);
}, [error]);
return (
<div>
<h2>Something went wrong!</h2>
<button
onClick={
// reset()은 별거없다. 그냥 에러바운더리 내의 컴포넌트만 새로고침하듯, re-rendering시켜주는게 전부다.
() => reset()
}
>
Try again
</button>
</div>
);
}
global-error.js
- app/error.js 경계는 루트 app/layout.js 또는 app/template.js 컴포넌트에서 발생하는 오류를 포착하지 못한다.
- 이러한 루트 컴포넌트에서 발생하는 오류를 구체적으로 처리하려면 루트 앱 디렉터리에 있는 app/global-error.js라는 error.js의 변형을 사용해야한다.
- 루트 error.js와 달리 global-error.js 에러 바운더리는 전체 애플리케이션을 감싸며, 해당 폴백 컴포넌트가 활성화되면 루트 레이아웃을 대체한다. 따라서 global-error.js는 자체 <html> 및 <body> 태그를 정의해야 한다.
- global-error.js 에러 바운더리는 다른 error.js 경계가 대부분의 오류를 포착하므로 자주 트리거되지 않을 가능성이 높다.
->global-error.js가 멍청해서 에러를 못잡아낸다는 소리가 아니고, 가장 가까운 에러바운더리에서 에러를 핸들링할거니까, 최상단에 위치한 global-error.js는 자주 작동하지 않을거라는 의미다. 만약 global-error.js만 설정하고, 다른 segment에 error바운더리를 설정하지 않았으면 에러가 발생했을때 무조건 global-error가 작동한다. <- ("Errors bubble up to the nearest parent error boundary." -> 부모가 없으면 에러바운더리의 조부모의 조부모까지 달려가서라도 에러를 핸들링하므로) - 오류메시지
- 서버컴포넌트에서 오류가 발생하면, 오류객체에는 민감한 세부정보가 클라이언트에 유출되지 않도록 일반 메시지와 오류를 조금 간략하게 적은 내용만 들어있다.
- 클라이언트컴포넌트에서 발생하는 오류 객체는 직렬화되며 디버깅을 쉽게 할 수 있도록 원래 오류의 메시지를 포함하고 있다.
'use client'
export default function GlobalError({
error,
reset,
}: {
error: Error
reset: () => void
}) {
return (
// global-error에는 반드시 <html>태그와 <body>태그 들어가야함!!
<html>
<body>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</body>
</html>
)
}