에러 처리

Nuxt에서 에러를 포착하고 처리하는 방법을 알아보세요.

Nuxt는 풀스택 프레임워크이므로, 서로 다른 컨텍스트에서 발생할 수 있는 여러 가지 방지 불가능한 사용자 런타임 에러의 원천이 있습니다:

  • Vue 렌더링 라이프사이클 중의 에러 (SSR & CSR)
  • 서버 및 클라이언트 시작 에러 (SSR + CSR)
  • Nitro 서버 라이프사이클 중의 에러 (server/ 디렉터리)
  • JS 청크 다운로드 중 에러
SSRServer-Side Rendering(서버 사이드 렌더링), CSR은 **Client-Side Rendering(클라이언트 사이드 렌더링)**을 의미합니다.

Vue Errors

onErrorCaptured를 사용하여 Vue 에러에 훅을 걸 수 있습니다.

추가로, Nuxt는 최상위 레벨까지 전파되는 모든 에러가 발생했을 때 호출되는 vue:error 훅을 제공합니다.

에러 리포팅 프레임워크를 사용 중이라면, vueApp.config.errorHandler를 통해 전역 핸들러를 제공할 수 있습니다. 이 핸들러는 처리된 에러를 포함한 모든 Vue 에러를 받게 됩니다.

plugins/error-handler.ts
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.config.errorHandler = (error, instance, info) => {
    // 에러 처리, 예: 서비스로 리포트
  }

  // 이렇게도 가능합니다
  nuxtApp.hook('vue:error', (error, instance, info) => {
    // 에러 처리, 예: 서비스로 리포트
  })
})
vue:error 훅은 onErrorCaptured 라이프사이클 훅을 기반으로 합니다.

Startup Errors

Nuxt 애플리케이션을 시작하는 동안 에러가 발생하면 Nuxt는 app:error 훅을 호출합니다.

여기에는 다음이 포함됩니다:

  • Nuxt 플러그인 실행
  • app:createdapp:beforeMount 훅 처리
  • Vue 앱을 HTML로 렌더링 (SSR 중)
  • 앱 마운트 (클라이언트 사이드) — 이 경우는 onErrorCaptured 또는 vue:error로 처리하는 것이 좋습니다.
  • app:mounted 훅 처리

Nitro Server Errors

현재로서는 이러한 에러에 대한 서버 사이드 핸들러를 정의할 수는 없지만, 에러 페이지를 렌더링할 수 있습니다. 에러 페이지 렌더링 섹션을 참고하세요.

Errors with JS Chunks

네트워크 연결 실패 또는 새로운 배포(이전 해시된 JS 청크 URL이 무효화됨)로 인해 청크 로딩 에러가 발생할 수 있습니다. Nuxt는 라우트 네비게이션 중 청크 로딩에 실패했을 때 하드 리로드를 수행하여 청크 로딩 에러를 처리하는 기능을 내장하고 있습니다.

이 동작은 experimental.emitRouteChunkErrorfalse로 설정하여(이러한 에러에 전혀 훅을 걸지 않도록 비활성화) 변경할 수 있으며, 직접 처리하고 싶다면 manual로 설정할 수 있습니다. 청크 로딩 에러를 수동으로 처리하고 싶다면, 아이디어를 얻기 위해 자동 구현체를 참고할 수 있습니다.

Error Page

Nuxt가 치명적인 에러(서버에서 처리되지 않은 모든 에러 또는 클라이언트에서 fatal: true로 생성된 에러)를 만나면, JSON 응답(Accept: application/json 헤더로 요청된 경우)을 렌더링하거나 전체 화면 에러 페이지를 트리거합니다.

서버 라이프사이클 중 다음과 같은 경우에 에러가 발생할 수 있습니다:

  • Nuxt 플러그인 처리 중
  • Vue 앱을 HTML로 렌더링하는 중
  • 서버 API 라우트에서 에러를 던지는 경우

또한 클라이언트 사이드에서도 다음과 같은 경우에 발생할 수 있습니다:

  • Nuxt 플러그인 처리 중
  • 애플리케이션 마운트 전(app:beforeMount 훅)
  • onErrorCaptured 또는 vue:error 훅으로 처리되지 않은 상태에서 앱을 마운트하는 경우
  • Vue 앱이 브라우저에서 초기화 및 마운트될 때(app:mounted).
모든 Nuxt 라이프사이클 훅을 살펴보세요.

기본 에러 페이지를 커스터마이즈하려면, 애플리케이션의 소스 디렉터리에서 app.vue와 나란히 ~/error.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">
      Clear errors
    </button>
  </div>
</template>
error.vue와 그 사용법에 대해 더 알아보세요.

커스텀 에러의 경우, 페이지/컴포넌트의 setup 함수에서 호출할 수 있는 onErrorCaptured 컴포저블이나 Nuxt 플러그인에서 설정할 수 있는 vue:error 런타임 Nuxt 훅을 사용하는 것을 강력히 권장합니다.

plugins/error-handler.ts
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.hook('vue:error', (err) => {
    //
  })
})

에러 페이지를 제거할 준비가 되면, 선택적으로 리다이렉트할 경로(예: '안전한' 페이지로 이동하고 싶은 경우)를 인자로 받는 clearError 헬퍼 함수를 호출할 수 있습니다.

플러그인에 의존하는 $routeuseRouter 같은 것을 사용하기 전에 반드시 확인하세요. 플러그인이 에러를 던졌다면, 에러를 지우기 전까지는 다시 실행되지 않습니다.
에러 페이지를 렌더링하는 것은 완전히 별도의 페이지 로드이므로, 등록된 모든 미들웨어가 다시 실행됩니다. 미들웨어에서 useError를 사용하여 에러가 처리 중인지 확인할 수 있습니다.
Node 16에서 실행 중이고 에러 페이지를 렌더링할 때 쿠키를 설정하면, 이전에 설정된 쿠키가 덮어써집니다. Node 16은 2023년 9월에 지원 종료(EOL)되었으므로, 더 최신 버전의 Node 사용을 권장합니다.

Error Utils

useError

TS Signature
function useError (): Ref<Error | { url, statusCode, statusMessage, message, description, data }>

이 함수는 현재 처리 중인 전역 Nuxt 에러를 반환합니다.

useError 컴포저블에 대해 더 알아보세요.

createError

TS Signature
function createError (err: string | { cause, data, message, name, stack, statusCode, statusMessage, fatal }): Error

추가 메타데이터와 함께 에러 객체를 생성합니다. 에러 message로 설정할 문자열이나 에러 속성을 포함하는 객체를 전달할 수 있습니다. 이는 앱의 Vue와 서버 부분 모두에서 사용할 수 있으며, 던져서 사용하도록 설계되었습니다.

createError로 생성한 에러를 던지면:

  • 서버 사이드에서는 전체 화면 에러 페이지를 트리거하며, clearError로 이를 지울 수 있습니다.
  • 클라이언트 사이드에서는 직접 처리할 수 있는 비치명적(non-fatal) 에러를 던집니다. 전체 화면 에러 페이지를 트리거해야 한다면 fatal: true를 설정하면 됩니다.
pages/movies/[slug].vue
<script setup lang="ts">
const route = useRoute()
const { data } = await useFetch(`/api/movies/${route.params.slug}`)

if (!data.value) {
  throw createError({
    statusCode: 404,
    statusMessage: 'Page Not Found',
  })
}
</script>
createError 유틸에 대해 더 알아보세요.

showError

TS Signature
function showError (err: string | Error | { statusCode, statusMessage }): Error

클라이언트 사이드에서는 언제든지, 서버 사이드에서는 미들웨어, 플러그인 또는 setup() 함수 안에서 직접 이 함수를 호출할 수 있습니다. 이 함수는 전체 화면 에러 페이지를 트리거하며, clearError로 이를 지울 수 있습니다.

대신 throw createError()를 사용하는 것을 권장합니다.

showError 유틸에 대해 더 알아보세요.

clearError

TS Signature
function clearError (options?: { redirect?: string }): Promise<void>

이 함수는 현재 처리 중인 Nuxt 에러를 제거합니다. 또한 선택적으로 리다이렉트할 경로(예: '안전한' 페이지로 이동하고 싶은 경우)를 인자로 받을 수 있습니다.

clearError 유틸에 대해 더 알아보세요.

Render Error in Component

Nuxt는 전체 사이트를 에러 페이지로 대체하지 않고도 앱 내에서 클라이언트 사이드 에러를 처리할 수 있게 해주는 <NuxtErrorBoundary> 컴포넌트도 제공합니다.

이 컴포넌트는 기본 슬롯 내에서 발생하는 에러를 처리하는 역할을 합니다. 클라이언트 사이드에서 에러가 최상위 레벨로 전파되는 것을 막고, 대신 #error 슬롯을 렌더링합니다.

#error 슬롯은 error를 prop으로 받습니다. (error = null로 설정하면 기본 슬롯을 다시 렌더링하게 됩니다. 이때 에러가 완전히 해결되었는지 먼저 확인해야 하며, 그렇지 않으면 에러 슬롯이 다시 한 번 렌더링될 뿐입니다.)

다른 라우트로 이동하면 에러는 자동으로 지워집니다.
app/pages/index.vue
<template>
  <!-- some content -->
  <NuxtErrorBoundary @error="someErrorLogger">
    <!-- 기본 슬롯을 사용해 콘텐츠를 렌더링합니다 -->
    <template #error="{ error, clearError }">
      여기에서 로컬하게 에러를 표시할 수 있습니다: {{ error }}
      <button @click="clearError">
        이 버튼은 에러를 지웁니다.
      </button>
    </template>
  </NuxtErrorBoundary>
</template>
Read and edit a live example in Docs > 4 X > Examples > Advanced > Error Handling.