Олег Марков
Как отлавливать и обрабатывать ошибки в Nuxt
Введение
Когда вы работаете с Nuxt, особенно в больших проектах, грамотная обработка ошибок становится одним из ключевых аспектов обеспечения устойчивости вашего приложения и хорошего пользовательского опыта. Nuxt — это прогрессивный фреймворк для Vue, который поддерживает как SSR (server-side rendering), так и статическую генерацию. При этом часто ошибки могут возникать на стадии асинхронной загрузки данных, в middlewares, плагинах или прямо на страницах приложения.
В этой статье я покажу разные подходы к обработке ошибок в Nuxt. Мы рассмотрим встроенные средства, создания кастомных error-страниц, обработку ошибок в middlewares, плагинах, asyncData и fetch, а также популярные паттерны для передачи ошибок между серверами и клиентами. Давайте разберемся, на каких слоях вообще появляются ошибки и как их можно контролировать.
Как и где могут возникать ошибки в Nuxt
Ошибки могут появиться почти в любом месте Nuxt-приложения:
- При загрузке страницы (например, из-за ошибок в методах asyncData или fetch)
- В middlewares (например, при авторизации)
- В методах жизненного цикла компонентов Vue
- Во внешних API-запросах
- В серверных функциях или при сетевых сбоях
- В плагинах Nuxt
Nuxt оборудован своими механизмами для обнаружения и глобальной обработки ошибок, чтобы вы могли перехватывать их на раннем этапе и корректно информировать пользователя.
Эффективная отладка и обработка ошибок критически важны для создания стабильных и надежных Nuxt-приложений. Однако, чтобы по-настоящему овладеть этим искусством, необходимо понимать внутренние механизмы Nuxt, включая его жизненный цикл, роутинг и обработку запросов. Если вы хотите узнать больше о том, как профессионально отлаживать и обрабатывать ошибки в Nuxt, приходите на наш большой курс Nuxt - fullstack Vue фреймворк. На курсе 129 уроков и 13 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.
Built-In обработка ошибок Nuxt — стандартные возможности
Nuxt автоматически отлавливает ошибки во многих процессах, связанных с загрузкой страницы. Например, если что-то идет не так в asyncData, Nuxt покажет стандартную страницу ошибки с соответствующим сообщением и HTTP-статусом.
Глобальная страница ошибок layouts/error.vue
Для обработки ошибок вы можете создать файл layouts/error.vue
. Всякий раз, когда в вашем приложении возникает ошибка, Nuxt отрендерит именно этот компонент. Смотрите, как это выглядит:
<template>
<div class="error">
<h1>Ошибка {{ error.statusCode }}</h1>
<p>{{ error.message }}</p>
<!-- Можно добавить кастомный дизайн -->
</div>
</template>
<script>
export default {
props: {
error: {
type: Object,
required: true
}
}
}
</script>
Здесь объект error
приходит автоматически от Nuxt. Обычно он содержит поля statusCode
и message
.
Теперь любую ошибку, возникшую где-либо в вашем проекте, вы сможете красиво отобразить пользователю, а не просто показать «страницу по умолчанию».
Обработка ошибок в asyncData и fetch
Загрузка данных на сервере — частый источник ошибок. Nuxt предоставляет удобный способ явно выбрасывать и ловить такие ошибки.
asyncData
В любом Page-компоненте вы можете выбросить ошибку с помощью функции error
:
export default {
async asyncData({ params, error }) {
// Допустим, не нашли нужный элемент
const data = await fetchData(params.id)
if (!data) {
// Передаем объект с настройками ошибки
error({ statusCode: 404, message: 'Данные не найдены' })
return
}
// Возвращаем данные в компонент
return { data }
}
}
В таком случае, если данных нет, вызывается ваш кастомный error-обработчик, а Nuxt отрендерит layouts/error.vue
.
fetch (для Nuxt 2.12+)
Если вы используете новый синтаксис fetch:
export default {
async fetch({ params, error }) {
try {
this.data = await apiGet(params.id)
} catch (e) {
// В случае ошибки, показываем ее через error функцию
error({ statusCode: 500, message: 'Ошибка запроса API' })
}
}
}
Пояснения
- В обоих случаях, если вы вызовете функцию
error
, страница не продолжит рендериться далее. - Объекты, передаваемые в
error
, должны содержать хотя быstatusCode
и/илиmessage
для корректного отображения.
Обработка ошибок в middleware
Middleware (промежуточные обработчики) в Nuxt часто отвечают за аутентификацию, проверки прав или перенаправления. Ошибки здесь тоже можно обрабатывать централизованно.
Пример middleware-перехватчика:
// middleware/auth.js
export default function ({ store, redirect, error }) {
// Проверяем, авторизован ли пользователь
if (!store.state.loggedIn) {
// Можно сделать редирект или показать страницу/ошибку
error({ statusCode: 401, message: 'Требуется авторизация' })
}
}
Если вызвать функцию error
в middleware, Nuxt так же отобразит кастомную страницу ошибки.
Глобальная обработка ошибок — использование плагинов
В сложных проектах вы можете захотеть улавливать ошибки на клиенте или сервере вне контекста страницы или middleware. В этом случае подойдут плагины.
Добавление слушателя ошибок
Создайте плагин, который будет отслеживать ошибки на уровне приложения:
// plugins/capture-errors.js
export default ({ $axios, redirect }) => {
$axios.onError(error => {
// Здесь можно логировать ошибку или делать кастомное поведение
if (error.response && error.response.status === 401) {
redirect('/login')
}
// Можно добавить отправку ошибок в Sentry или другой сервис
})
}
И не забудьте подключить этот плагин в конфиге nuxt.config.js
:
export default {
plugins: ['~/plugins/capture-errors.js']
}
Сервисы логирования и внешние наглдяющие системы
Для сложных приложений полезно сохранять критические ошибки и передавать их в сторонние сервисы: Sentry, Bugsnag и т. п.
Пример интеграции Sentry:
// plugins/sentry.js
import * as Sentry from '@sentry/browser'
export default ({ app }) => {
Sentry.init({
dsn: 'ВАШ_DSN_КЛЮЧ',
integrations: [new Sentry.Integrations.Vue({ Vue: app.Vue })]
})
}
В error.vue или в error-функциях можно отправлять данные об ошибке:
asyncData({ error }) {
try {
// Запрос к API
} catch (err) {
Sentry.captureException(err)
error({ statusCode: 500, message: 'Критическая ошибка' })
}
}
Серверные ошибки и fallback-обработка
Когда вы работаете в SSR-режиме, часть ошибок скрывается от пользователя или выдается в виде универсальной серверной ошибки. Чтобы тонко управлять этими случаями, используйте кастомные middleware или глобальные обработчики Node.js.
Пример серверного middleware (SSR)
В Nuxt вы можете добавить серверный middleware в /server-middleware
:
// server-middleware/error-handler.js
module.exports = function (req, res, next) {
try {
next()
} catch (err) {
// Желательно логировать критические ошибки в отдельном месте
res.statusCode = 500
res.end('Серверная ошибка')
}
}
В nuxt.config.js
:
export default {
serverMiddleware: ['~/server-middleware/error-handler.js']
}
Пользовательские страницы ошибок для разных статусов
В error.vue вы можете кастомизировать отображение для разных статусов, делая UX более дружелюбным.
<template>
<div>
<component :is="errorComponent" :error="error" />
</div>
</template>
<script>
import NotFound from '~/components/NotFound.vue'
import ServerError from '~/components/ServerError.vue'
export default {
props: ['error'],
computed: {
errorComponent() {
if (this.error.statusCode === 404) return NotFound
if (this.error.statusCode === 500) return ServerError
return 'div'
}
}
}
</script>
Теперь вы сможете давать понятные сообщения и разные стили для пользовательских и системных ошибок.
Клиентская обработка ошибок
Не все ошибки видит сервер. Иногда ошибки (например, в компоненте) можно перехватывать через errorCaptured
или через глобальный обработчик Vue.
Глобальный обработчик для клиента
// plugins/global-error-handler.js
export default ({ app }) => {
app.vueApp.config.errorHandler = (err, vm, info) => {
// Можно логировать или показывать всплывающее уведомление
console.error('В приложении ошибка:', err, info)
}
}
Использование try-catch в компонентах и методах
Иногда ошибки случаются не при загрузке страницы, а при действиях пользователя. В этом случае используем обычный try-catch:
methods: {
async onSave() {
try {
await this.$axios.$post('/api/save', this.data)
this.$toast.success('Успешно сохранено')
} catch (e) {
// Можно передать ошибку на страницу error или показать уведомление
this.$toast.error('Ошибка при сохранении')
}
}
}
Такой подход помогает локально управлять ошибками и не портит весь UX приложения.
Паттерн с передачей ошибок между сервером и клиентом
Для сложных ошибок, которые идут от сервера и должны быть показаны на клиенте, удобно передавать ошибки во Vuex:
// store/index.js
export const state = () => ({
serverError: null
})
export const mutations = {
setServerError(state, error) {
state.serverError = error
}
}
А затем показывать их через уведомления или кастомные блоки интерфейса.
Ошибки во время маршрутизации
Если страница или компонент не найден — это выбрасывает 404 ошибку автоматически через Nuxt-роутинг. Но можно дискриминировать разные сценарии:
// middleware/check-route.js
export default function({ route, error }) {
const knownRoutes = ['/main', '/profile']
if (!knownRoutes.includes(route.path)) {
error({ statusCode: 404, message: 'Страница не найдена!' })
}
}
Примеры типовых сценариев
Пример — неправильный путь к API
asyncData({ error }) {
return this.$axios.$get('/wrong/api/path')
.catch(err => {
// Приводим ошибку к форматированному виду
if (err.response && err.response.status === 400) {
error({ statusCode: 400, message: 'Некорректный запрос' })
} else {
error({ statusCode: 500, message: 'Неизвестная ошибка сервера' })
}
})
}
Пример — обработка авторизации в middleware
export default function({ store, redirect, error, route }) {
if (!store.getters.isAuthenticated && route.path !== '/login') {
// Неавторизованный доступ — выводим ошибку
error({ statusCode: 401, message: 'Вы не авторизованы' })
}
}
Различия обработки ошибок на сервере и на клиенте
- SSR — ошибки можно и нужно отлавливать в asyncData, plugins, middleware.
- Клиент — используйте errorCaptured, глобальный errorHandler, try-catch.
- Ошибки в fetch/asyncData чаще всего ведут к отображению кастомного error.vue.
- В компонентах лучше ловить ошибки локально, чтобы не ломать весь flow пользователя.
Вывод
Nuxt предлагает продуманные средства для организации реактивной и централизованной обработки ошибок, которые легко интегрируются в существующую архитектуру приложения. Вы можете задать различную логику для разных источников ошибок, кастомизировать страницы ошибок, интегрировать внешние системы мониторинга, а также управлять видимостью ошибок во время SSR и на клиенте. Немного доработав стандартные паттерны, вы получите стабильное и предсказуемое поведение даже в сложных ситуациях.
Отладка и обработка ошибок — это лишь часть процесса разработки. Чтобы создавать полноценные и качественные Nuxt-приложения, необходимо освоить все аспекты фреймворка, от настройки окружения и работы с данными до SEO-оптимизации и развертывания в production. На нашем курсе Nuxt - fullstack Vue фреймворк вы найдете все необходимые знания и навыки для достижения успеха. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в Nuxt прямо сегодня.
Частозадаваемые технические вопросы по теме статьи и ответы на них
Как получить доступ к error-функции вне asyncData или fetch?
Если вы хотите вызвать error вне asyncData/fetch (например, в методе компонента), вам придется эмулировать такое поведение локально: например, с помощью Vuex или показа модального окна ошибки. error-функция автоматически пробрасывается только во входных параметрах методов asyncData, fetch, middleware.
Как отправить error с дополнительными данными (например, stack trace) на сервер?
Внутри error-функции можно передать объект с любым числом полей. Для передачи данных на сервер используйте подключённый внешний сервис (например, Sentry) или отправляйте данные по API вручную внутри catch-блока перед вызовом error.
Как отловить ошибки, которые не попадают ни в одну из описанных категорий?
Если у вас происходят ошибки в сторонних библиотеках или во Vue-компонентах, используйте глобальный errorHandler (Nuxt 3: app.vueApp.config.errorHandler; Nuxt 2: Vue.config.errorHandler). Либо настройте обработчик window.onerror для браузерных ошибок.
Как обработать ошибку при статической генерации (nuxt generate)?
Ошибки, возникшие на стадии nuxt generate
, отображаются в консоли терминала. Чтобы сделать обработку ошибок внутри генерации кастомной, отлавливайте их внутри asyncData/fetch и отдавайте корректный статус/error-страницу или сообщение для генератора.
Почему моя кастомная страница error.vue не отображается на клиенте при ошибках в компонентах?
Если ошибка не произошла в asyncData/fetch/middleware или не проброшена error-функцией, Nuxt не вызовет error.vue автоматически. Для таких ошибок используйте $root.$emit/$on или глобальный errorHandler, чтобы вручную показать всплывающие уведомления или модальные окна.
Постройте личный план изучения Nuxt до уровня Middle — бесплатно!
Nuxt — часть карты развития Frontend
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по Nuxt
Лучшие курсы по теме

Nuxt
Антон Ларичев
TypeScript с нуля
Антон Ларичев