Vue Router предоставляет гибкие возможности для управления маршрутизацией в приложениях на Vue.js. Одной из важных задач является корректная обработка ошибок навигации, которые могут возникать при переходе между маршрутами. Ошибки навигации могут возникать по различным причинам: дублирование перехода на текущий маршрут, отказ в доступе к маршруту, некорректные параметры или проблемы при асинхронной загрузке компонентов.
Vue Router различает несколько основных типов ошибок:
NavigationDuplicated Возникает при попытке перейти на текущий маршрут. Например:
this.$router.push('/home')
.catch(err => {
if (err.name === 'NavigationDuplicated') {
console.log('Переход на текущий маршрут проигнорирован');
}
});
Ключевой момент: ошибка NavigationDuplicated не является критической и часто может игнорироваться, так как переход не приводит к нарушению логики приложения.
NavigationGuardError Ошибки, вызванные
навигационными охранниками (beforeEach,
beforeEnter, beforeRouteEnter). Пример
обработки:
router.beforeEach((to, from, next) => {
if (!user.isAuthenticated && to.meta.requiresAuth) {
next(new Error('Доступ запрещён'));
} else {
next();
}
});
router.onError(err => {
console.error('Ошибка навигации:', err.message);
});
Здесь router.onError позволяет глобально перехватывать
ошибки, которые возникли во время выполнения охранников.
AsyncComponentError Возникает при ошибках загрузки асинхронных компонентов, подключённых к маршрутам:
const AsyncPage = () => import('./components/AsyncPage.vue');
router.addRoute({
path: '/async',
component: AsyncPage
});
router.onError(err => {
if (/Loading chunk \d+ failed/.test(err.message)) {
console.warn('Ошибка загрузки асинхронного компонента');
}
});
Часто такие ошибки связаны с сетевыми сбоями или некорректным сборщиком модулей.
Vue Router предоставляет несколько способов безопасного управления ошибками:
Promise-подход при push/replace
Методы push и replace возвращают промис.
Можно перехватывать ошибки, используя .catch:
this.$router.push({ name: 'profile', params: { id: 1 } })
.catch(err => {
if (err.name !== 'NavigationDuplicated') {
console.error('Ошибка перехода:', err);
}
});
Важно фильтровать ошибки NavigationDuplicated, чтобы не захламлять консоль ненужными сообщениями.
Глобальный обработчик onError
router.onError(err => {
console.error('Произошла ошибка навигации:', err);
// Можно перенаправить пользователя на страницу ошибки
router.push('/error');
});
Этот подход полезен для централизованного логирования и отображения страниц с информацией об ошибках.
Обработка ошибок в навигационных охранниках
Навигационные охранники могут возвращать ошибку вместо вызова
next():
router.beforeEach((to, from, next) => {
try {
if (to.meta.requiresAdmin && !user.isAdmin) {
throw new Error('Нет прав доступа');
}
next();
} catch (err) {
next(err);
}
});
Ошибки, переданные через next(err), могут быть
перехвачены глобально с помощью router.onError.
Фильтрация ошибок NavigationDuplicated Наиболее частая причина ошибок навигации — повторный переход на текущий маршрут. Логирование или игнорирование таких ошибок делает приложение чище и безопаснее.
Глобальная обработка критических ошибок
Использование router.onError позволяет централизованно
реагировать на ошибки: показывать уведомления, перенаправлять на
страницу ошибки, логировать для аналитики.
Разделение логики навигации и бизнес-логики Не рекомендуется помещать сложные операции с данными напрямую в охранники маршрутов. Ошибки лучше обрабатывать на уровне промисов компонентов и асинхронной загрузки.
Обработка ошибок асинхронных компонентов Использование динамического импорта требует отлавливания ошибок загрузки, чтобы избежать «сломанных» страниц при проблемах сети.
router.push('/dashboard')
.catch(err => {
if (err.name === 'NavigationDuplicated') return;
console.error('Ошибка перехода:', err);
router.push('/error');
});
router.onError(err => {
console.error('Глобальная ошибка навигации:', err);
});
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !user.isAuthenticated) {
next(new Error('Неавторизованный доступ'));
} else {
next();
}
});
router.onError(err => {
alert(`Произошла ошибка: ${err.message}`);
router.push('/');
});
Эти подходы совместно обеспечивают надежную обработку ошибок на всех уровнях маршрутизации: при программном переходе, через охранники и при асинхронной загрузке компонентов.