에러 처리
Nuxt는 풀스택 프레임워크이기 때문에, 다양한 컨텍스트에서 방지할 수 없는 사용자 런타임 에러가 여러 소스에서 발생할 수 있습니다:
- Vue 렌더링 라이프사이클 중 발생하는 에러 (SSR & CSR)
- 서버 및 클라이언트 시작 시 에러 (SSR + CSR)
- Nitro 서버 라이프사이클 중 발생하는 에러 (
server/디렉토리) - JS 청크 다운로드 중 발생하는 에러
Vue 에러
onErrorCaptured를 사용하여 Vue 에러를 후킹할 수 있습니다.
추가로, Nuxt는 vue:error 훅을 제공하며, 이 훅은 에러가 최상위로 전파될 때 호출됩니다.
에러 리포팅 프레임워크를 사용하는 경우, vueApp.config.errorHandler를 통해 전역 핸들러를 제공할 수 있습니다. 이 핸들러는 처리된 에러를 포함한 모든 Vue 에러를 수신합니다.
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.config.errorHandler = (error, instance, info) => {
// 에러 처리, 예: 서비스에 리포트
}
// 이렇게도 가능
nuxtApp.hook('vue:error', (error, instance, info) => {
// 에러 처리, 예: 서비스에 리포트
})
})
vue:error 훅은 onErrorCaptured 라이프사이클 훅을 기반으로 합니다.시작 시 에러
Nuxt는 Nuxt 애플리케이션 시작 중 에러가 발생하면 app:error 훅을 호출합니다.
이에는 다음이 포함됩니다:
- Nuxt 플러그인 실행
app:created및app:beforeMount훅 처리- Vue 앱을 HTML로 렌더링(SSR 중)
- 앱 마운트(클라이언트 사이드) - 이 경우는
onErrorCaptured또는vue:error로 처리해야 합니다. app:mounted훅 처리
Nitro 서버 에러
현재 이 에러들에 대해 서버 사이드 핸들러를 정의할 수는 없지만, 에러 페이지를 렌더링할 수 있습니다. 자세한 내용은 에러 페이지 렌더링 섹션을 참고하세요.
JS 청크 관련 에러
네트워크 연결 실패나 새로운 배포(이전의 해시된 JS 청크 URL이 무효화됨)로 인해 청크 로딩 에러가 발생할 수 있습니다. Nuxt는 라우트 네비게이션 중 청크 로딩에 실패하면 하드 리로드를 수행하여 청크 로딩 에러를 처리하는 내장 지원을 제공합니다.
이 동작은 experimental.emitRouteChunkError를 false로 설정하여(이 에러 후킹을 완전히 비활성화) 변경할 수 있으며, 직접 처리하고 싶다면 manual로 설정할 수 있습니다. 청크 로딩 에러를 직접 처리하고 싶다면 자동 구현 예시를 참고하세요.
에러 페이지
fatal: true로 생성된 에러)가 발생하면, JSON 응답(Accept: application/json 헤더로 요청 시) 또는 전체 화면 에러 페이지가 렌더링됩니다.서버 라이프사이클 중 다음과 같은 경우 에러가 발생할 수 있습니다:
- Nuxt 플러그인 처리 중
- Vue 앱을 HTML로 렌더링 중
- 서버 API 라우트에서 에러가 발생한 경우
클라이언트 사이드에서는 다음과 같은 경우 에러가 발생할 수 있습니다:
- Nuxt 플러그인 처리 중
- 애플리케이션 마운트 전(
app:beforeMount훅) onErrorCaptured또는vue:error훅으로 처리되지 않은 경우 앱 마운트 시- 브라우저에서 Vue 앱이 초기화 및 마운트될 때(
app:mounted)
기본 에러 페이지를 커스터마이즈하려면, 애플리케이션의 소스 디렉토리(예: app.vue와 같은 위치)에 ~/error.vue를 추가하세요.
<script setup lang="ts">
import type { NuxtError } from '#app'
const props = defineProps({
error: Object as () => NuxtError
})
const handleError = () => clearError({ redirect: '/' })
</script>
<template>
<div>
<h2>{{ error?.statusCode }}</h2>
<button @click="handleError">에러 지우기</button>
</div>
</template>
커스텀 에러의 경우, 페이지/컴포넌트 setup 함수에서 호출할 수 있는 onErrorCaptured 컴포저블이나 Nuxt 플러그인에서 설정할 수 있는 vue:error 런타임 훅 사용을 강력히 권장합니다.
export default defineNuxtPlugin(nuxtApp => {
nuxtApp.hook('vue:error', (err) => {
//
})
})
에러 페이지를 제거할 준비가 되면, clearError 헬퍼 함수를 호출할 수 있습니다. 이 함수는 리디렉션할 경로(예: '안전한' 페이지로 이동하고 싶을 때)를 옵션으로 받을 수 있습니다.
$route나 useRouter와 같은 것을 사용하기 전에 반드시 확인하세요. 플러그인에서 에러가 발생했다면, 에러를 지우기 전까지는 플러그인이 다시 실행되지 않습니다.useError를 사용할 수 있습니다.에러 유틸리티
useError
function useError (): Ref<Error | { url, statusCode, statusMessage, message, description, data }>
이 함수는 현재 처리 중인 전역 Nuxt 에러를 반환합니다.
createError
function createError (err: string | { cause, data, message, name, stack, statusCode, statusMessage, fatal }): Error
추가 메타데이터가 포함된 에러 객체를 생성합니다. 에러 message로 설정할 문자열이나 에러 속성을 포함하는 객체를 전달할 수 있습니다. 이 함수는 앱의 Vue와 서버 부분 모두에서 사용할 수 있으며, throw를 위해 설계되었습니다.
createError로 생성한 에러를 throw하면:
- 서버 사이드에서는 전체 화면 에러 페이지가 표시되며,
clearError로 지울 수 있습니다. - 클라이언트 사이드에서는 비치명적 에러가 throw되어 직접 처리할 수 있습니다. 전체 화면 에러 페이지를 표시하려면
fatal: true를 설정하면 됩니다.
<script setup lang="ts">
const route = useRoute()
const { data } = await useFetch(`/api/movies/${route.params.slug}`)
if (!data.value) {
throw createError({
statusCode: 404,
statusMessage: '페이지를 찾을 수 없습니다'
})
}
</script>
showError
function showError (err: string | Error | { statusCode, statusMessage }): Error
이 함수는 클라이언트 사이드 어디서든, 또는(서버 사이드에서는) 미들웨어, 플러그인, setup() 함수 내에서 직접 호출할 수 있습니다. 전체 화면 에러 페이지가 표시되며, clearError로 지울 수 있습니다.
대신 throw createError() 사용을 권장합니다.
clearError
function clearError (options?: { redirect?: string }): Promise<void>
이 함수는 현재 처리 중인 Nuxt 에러를 지웁니다. 또한 리디렉션할 경로(예: '안전한' 페이지로 이동하고 싶을 때)를 옵션으로 받을 수 있습니다.
컴포넌트에서 에러 렌더링
Nuxt는 또한 앱 내에서 클라이언트 사이드 에러를 전체 사이트 에러 페이지로 대체하지 않고 처리할 수 있는 <NuxtErrorBoundary> 컴포넌트를 제공합니다.
이 컴포넌트는 기본 슬롯 내에서 발생한 에러를 처리합니다. 클라이언트 사이드에서는 에러가 최상위로 전파되는 것을 막고, 대신 #error 슬롯을 렌더링합니다.
#error 슬롯은 error를 prop으로 받습니다. (error = null로 설정하면 기본 슬롯이 다시 렌더링됩니다. 단, 에러가 완전히 해결된 후에만 해야 하며, 그렇지 않으면 에러 슬롯이 다시 렌더링됩니다.)
<template>
<!-- 일부 콘텐츠 -->
<NuxtErrorBoundary @error="someErrorLogger">
<!-- 기본 슬롯을 사용해 콘텐츠를 렌더링합니다 -->
<template #error="{ error, clearError }">
여기에서 에러를 로컬로 표시할 수 있습니다: {{ error }}
<button @click="clearError">
이 버튼을 누르면 에러가 지워집니다.
</button>
</template>
</NuxtErrorBoundary>
</template>