티스토리 뷰
Error Handling
공식 문서
공식문서에서 개발, 서버 측 및 클라이언트 측 오류를 처리하는 방법을 설명하고 있습니다 :) 해당 내용에 대해 살펴보도록 하겠습니다.
1. 개발 중 오류 처리
Next.js 개발 단계에서 런타임 오류가 발생하면 오버레이가 발생합니다 . 웹 페이지를 덮는 모달입니다. devlopment 모드로 실행될 때만 표시 되며 빌드 환경에서는 표시되지 않습니다. 오류를 수정하면 오버레이가 자동으로 해제됩니다.
2. 서버 오류 처리
서버 측 오류를 처리하기 위해 기본적으로 정적인 500 페이지를 제공합니다.
`500.js`라는 파일을 만들어 커스텀해서 에러 페이지를 보여줄 수도 있습니다. 마찬가지로 404, 401과 같이 에러 status code 이름으로 파일을 만들어 컴포넌트를 추가하면 해당 에러에 대해 만들어둔 Custom 에러 컴포넌트를 사용자에게 보여줄 수 있습니다.
📜 pages/404.js
export default function Custom404() {
return <h1>404 - Page Not Found</h1>
}
3. 오류 페이지 Customizing
다양한 status code에 대해 한번에 처리하고 싶다면 다음과 같이 사용할 수 있습니다.
📜 pages/_error.js
import ErrorNext from 'next/error'
function Error({ statusCode }) {
if (statusCode === 404) {
return <p>404에러에요!</p>
}
return <ErrorNext statusCode={statusCode} />
}
Error.getInitialProps = ({ res, err }) => {
const statusCode = res ? res.statusCode : err ? err.statusCode : 404
return { statusCode }
}
export default Error
`next/error`의 컴포넌트는 위에서 기본적으로 보여주었던 next에서 제공하고 있는 에러 컴포넌트입니다. 저는 위와 같이 내가 따로 처리하고 싶은 statusCode에 대해서는 특별하게 return 하고 있고 나머지에 대해서는 기본 컴포넌트를 사용하여 처리되도록 했습니다.
주의할 점은 예를 들어 이미 `404.js`파일이 존재한다면 404.js 파일을 먼저 인식하여 _error.js 파일로 인식이 되지 않습니다.
위에서는 제가 간단하게 작성했지만, 특정 statusCode에 대해 분기처리 하고 싶다고 하면
const getErrorMessage = status => {
switch (status) {
case 403:
return {
title: '세션이 만료되었습니다.',
content: '로그인을 해주세요',
}
// case 409:
case 500:
return {
title: '서버에서 오류가 발생하였습니다.',
content:
'잠시 후 다시 시도해주세요. 문제가 지속될 경우 고객 센터에 문의해 주세요.',
}
case 502:
return {
title: '연결 과정에서 문제가 발생하였습니다.',
content: '잠시 후 다시 시도해주세요.',
}
case 503:
return {
title: '서비스를 일시적으로 이용할 수 없습니다.',
content: '나중에 다시 시도해주세요.',
}
default:
return {
title: '서비스에 접속할 수 없습니다.',
content: '새로고침을 하거나 잠시 후 다시 접속해 주시기 바랍니다.',
}
}
}
export default getErrorMessage
위 처럼 따로 정의해두고 에러 컴포넌트에서 statusCode에 따라 처리하는 것도 좋은 방법일 것입니다.
4. 클라이언트 오류 처리
React의 ErrorBoundary에 대한 사용방법을 설명하고 있습니다.
Next.js에서 ErrorBoundary를 사용하려면 클래스 구성 요소를 생성하고 pages/_app.js를 래핑해야 합니다.
우선 ErrorBoundary 컴포넌트를 생성합니다.
📜 components/ErrorBoundary.js
import React from 'react'
/**
* Error 관련되어서는 hook에서 life cycle method가 존재하지 않아서
* class형 컴포넌트 사용이 불가피
*/
class ErrorBoundary extends React.Component {
constructor(props) {
super(props)
// 초기 상태를 setup
this.state = { hasError: false, error: null, errorInfo: null }
}
static getDerivedStateFromError(error) {
console.log(`getDerivedStateFromError: ${error}`)
return { hasError: true }
}
componentDidCatch(error, errorInfo) {
this.setState({ error, errorInfo })
console.log(`componentDidCatch: ${(error, errorInfo)}`)
}
render() {
if (this.state.hasError) {
if (this.props.fallbackComponent) {
// props로 받은 fallbackComponent가 있다면
return this.props.fallbackComponent
}
return (
<div>
<h2>Error occurred</h2>
<details style={{ whiteSpace: 'pre-wrap' }}>
{this.state.error && this.state.error.toString()}
</details>
</div>
)
}
return this.props.children
}
}
export default ErrorBoundary
위처럼 만들어준 ErrorBoundary 컴포넌트를 _app.js에서 래핑해줍니다.
📜 _app.js
import Layout from '@/components/Layout'
import '@/styles/globals.css'
import ErrorBoundary from '@/components/ErrorBoundary'
export default function App({ Component, pageProps }) {
return (
<Layout>
<ErrorBoundary>
<Component {...pageProps} pathname={router.pathname} />
</ErrorBoundary>
</Layout>
)
}
의도적으로 에러를 throw하여 테스트 해보았을 때 미리 Custom 해두었던 에러 메세지가 화면에 렌더링된 것을 확인할 수 있었습니다.
이번에는 fallbackComponent를 추가해봅시다.
<ErrorBoundary fallbackComponent={<div>에러 발생! 🚨</div>}>
<Component {...pageProps} pathname={router.pathname} />
</ErrorBoundary>
이번에는 fallbackComponent로 특별히 화면에 렌더하고 싶은 컴포넌트를 넘겨주었더니 해당 컴포넌트로 화면에 렌더링된 것을 확인할 수 있었습니다.
만약 에러가 런타임 에러 모달로 뜬다면 development 모드에서가 아닌 build 환경에서 확인해보시면 되겠습니다 :)
이번 포스팅에서는 Custom Error 컴포넌트를 통해 Error Handling에 대해 알아보았습니다.
1. Error
handled vs unhandled
2. Error Handling
Development / Server / Client
3. Error Page Custom
404.js / _error.js / next/error
4. Client
Error Boundary
'프론트엔드 > Next.js' 카테고리의 다른 글
[Next.js] next.config.js 옵션 알아보기 (0) | 2023.06.29 |
---|---|
[Next.js] Web vitals와 성능 측정 도구에 대해 알아보자 (0) | 2023.06.28 |
[Next.js] Custom App - 생산성을 높이는 _app.js에서 할 수 있는 일들 (0) | 2023.06.27 |
[Next.js] ../ 때문에 길어지는 import문은 별칭 절대경로 @ 사용하기 (0) | 2023.06.27 |
[Next.js] Dynamic Import(Lazy load) & Hydration & Static Export (0) | 2023.06.27 |
- Total
- Today
- Yesterday
- HTML
- 자바스크립트
- 데이터분석
- frontend
- 디프만
- rtl
- 자바
- testing
- 프론트엔드 공부
- 머신러닝
- react-query
- JSP
- 타입스크립트
- Python
- 딥러닝
- 리액트 훅
- 파이썬
- 인프런
- 리액트
- 프론트엔드
- next.js
- react
- CSS
- styled-components
- TypeScript
- jest
- 프로젝트 회고
- 자바스크립트 기초
- 프론트엔드 기초
- 스타일 컴포넌트 styled-components
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |