Обработка ошибок

Как перехватывать и обрабатывать ошибки в Nuxt.

Nuxt — фреймворк полного стека: ошибки времени выполнения могут возникать в разных контекстах:

  • Ошибки во время жизненного цикла рендеринга Vue (SSR & CSR)
  • Ошибки запуска сервера и клиента (SSR + CSR)
  • Ошибки во время жизненного цикла сервера Nitro (папка server/)
  • Ошибки загрузки JS чанков
SSRServer-Side Rendering (рендеринг на стороне сервера), CSRClient-Side Rendering (рендеринг на стороне клиента).

Ошибки Vue

Ошибки Vue можно перехватывать через onErrorCaptured.

Кроме того, Nuxt вызывает хук vue:error, если ошибка доходит до верхнего уровня.

Глобальный обработчик задаётся через vueApp.config.errorHandler: он получает все ошибки Vue, в том числе уже обработанные.

plugins/error-handler.ts
export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.config.errorHandler = (error, instance, info) => {
    // handle error, e.g. report to a service
  }

  // Also possible
  nuxtApp.hook('vue:error', (error, instance, info) => {
    // handle error, e.g. report to a service
  })
})
Обратите внимание, что хук vue:error основан на хуке жизненного цикла onErrorCaptured.

Ошибки запуска

Nuxt вызовет хук app:error, если возникут любые ошибки на старте вашего приложения Nuxt.

Это включает:

  • запуск плагинов Nuxt
  • обработку хуков app:created и app:beforeMount
  • рендеринг приложения Vue в HTML (во время SSR)
  • монтирование приложения (на стороне клиента), хотя вы должны обрабатывать этот случай с помощью onErrorCaptured или vue:error
  • обработку хука app:mounted

Ошибки сервера Nitro

Сейчас для таких ошибок нельзя задать отдельный серверный обработчик, но можно показать страницу ошибки — см. раздел «Страница ошибки».

Ошибки с чанками JS

Ошибки загрузки чанков возможны из‑за сети или нового развёртывания (старые URL хешированных JS-чанков перестают быть валидными). Nuxt по умолчанию при неудачной загрузке чанка во время навигации выполняет жёсткую перезагрузку страницы.

Вы можете изменить это поведение, установив experimental.emitRouteChunkError в значение false (чтобы отключить обработку этих ошибок вообще) или в значение manual, если вы хотите обрабатывать их самостоятельно. Если вы хотите обрабатывать ошибки загрузки фрагментов вручную, вы можете ознакомиться с автоматической реализацией для получения идей.

Страница ошибки

При фатальной ошибке (любая необработанная ошибка на сервере или на клиенте с fatal: true) Nuxt либо отдаёт JSON (если запрос с заголовком Accept: application/json), либо показывает полноэкранную страницу ошибки.

Ошибка может возникнуть на сервере, когда:

  • обрабатываются ваши плагины Nuxt
  • ваше Vue-приложение рендерится в HTML
  • маршрут API сервера кидает ошибку

Она также может возникнуть на стороне клиента, когда:

  • обрабатываются ваши плагины Nuxt
  • перед монтированием приложения (хук app:beforeMount)
  • монтируется ваше приложение, если ошибка не перехвачена onErrorCaptured или хуком vue:error
  • Vue приложение было инициализировано и смонтировано в браузере (app:mounted).
Узнайте все хуки жизненного цикла Nuxt.

Настройте страницу ошибки по умолчанию, добавив ~/error.vue в исходную директорию вашего приложения, рядом с 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?.status }}</h2>
    <button @click="handleError">
      Clear errors
    </button>
  </div>
</template>
Подробнее об error.vue и его использовании.

Для пользовательских ошибок мы настоятельно рекомендуем использовать композабл onErrorCaptured, который может быть вызван в setup-функции страницы/компонента или в рантайм-хуке Nuxt vue:error, который может быть настроен в Nuxt-плагине.

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

Когда вы будете готовы скрыть страницу ошибки, вы можете вызвать вспомогательную функцию clearError, которая принимает опциональный путь для редиректа (например, если вы хотите направить на 'безопасную' страницу).

Прежде чем использовать API, зависящие от плагинов Nuxt (например, $route или useRouter), убедитесь, что плагины отработали без ошибок: при сбое плагин не перезапустится, пока вы не устраните проблему.
Отрисовка страницы ошибки — это отдельная загрузка страницы: зарегистрированные посредники маршрута выполнятся снова. В посреднике можно вызвать useError, чтобы проверить, обрабатывается ли ошибка.
Если вы на Node 16 и при отрисовке страницы ошибки задаёте cookie, они перезапишут ранее установленные cookie. Рекомендуем перейти на более новую версию Node: срок поддержки Node 16 истёк в сентябре 2023 года.

Утилиты для ошибок

useError

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

Эта функция вернет глобальную ошибку Nuxt, которая обрабатывается.

Подробнее о композабле useError.

createError

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

Создаёт объект ошибки с дополнительными метаданными: строку-сообщение или объект с полями ошибки. Подходит и для Vue, и для серверного кода; предназначен для throw.

Если вы бросаете ошибку, созданную через createError:

  • на стороне сервера это вызовет полноэкранную страницу ошибки, которую вы можете очистить с помощью clearError.
  • на клиенте получится нефатальная ошибка для обработки в коде. Если вам нужно вызвать полноэкранную страницу ошибки, вы можете это сделать, установив 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({
    status: 404,
    statusText: 'Page Not Found',
  })
}
</script>
Свойство statusText предназначено для коротких текстов статуса в духе HTTP (например, «Not Found»). В нём должны быть только горизонтальные табы, пробелы и видимые ASCII-символы ([\t\u0020-\u007E]).Подробные описания, многострочные сообщения или текст с не-ASCII символами указывайте в свойстве message.
Подробнее об утилите createError.

showError

TS Signature
function showError (err: string | Error | { status, statusText }): Error

Вы можете вызвать эту функцию в любой момент на клиенте или (на сервере) непосредственно в посреднике маршрута, плагине или функциях setup(). Это вызовет полноэкранную страницу ошибки, которую вы можете очистить с помощью clearError.

Вместо этого рекомендуется использовать throw createError().

Подробнее об утилите showError.

clearError

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

Эта функция очистит текущую обработанную ошибку Nuxt. Она также принимает опциональный путь для редиректа (например, если вы хотите направить на 'безопасную' страницу).

Подробнее об утилите clearError.

Отображение ошибки в компоненте

Nuxt также предоставляет компонент <NuxtErrorBoundary>, который позволяет вам обрабатывать ошибки на стороне клиента в вашем приложении, не заменяя весь сайт страницей ошибки.

Этот компонент отвечает за обработку ошибок, возникающих в его слоте по умолчанию. На стороне клиента это предотвратит появление ошибки на верхнем уровне и вместо этого отобразит слот #error.

Слот #error получит error как входной параметр. (Если задать error = null, слот по умолчанию отрисуется снова; сначала убедитесь, что ошибка устранена, иначе слот #error покажется повторно.)

Если вы перейдете на другой маршрут, ошибка будет очищена автоматически.
pages/index.vue
<template>
  <!-- some content -->
  <NuxtErrorBoundary @error="someErrorLogger">
    <!-- You use the default slot to render your content -->
    <template #error="{ error, clearError }">
      You can display the error locally here: {{ error }}
      <button @click="clearError">
        This will clear the error.
      </button>
    </template>
  </NuxtErrorBoundary>
</template>
Прочитайте и отредактируйте живой пример в Docs > 3 X > Examples > Advanced > Error Handling.