Обработка ошибок навигации

Vue Router предоставляет гибкие возможности для управления маршрутизацией в приложениях на Vue.js. Одной из важных задач является корректная обработка ошибок навигации, которые могут возникать при переходе между маршрутами. Ошибки навигации могут возникать по различным причинам: дублирование перехода на текущий маршрут, отказ в доступе к маршруту, некорректные параметры или проблемы при асинхронной загрузке компонентов.


Типы ошибок навигации

Vue Router различает несколько основных типов ошибок:

  1. NavigationDuplicated Возникает при попытке перейти на текущий маршрут. Например:

    this.$router.push('/home')
        .catch(err => {
            if (err.name === 'NavigationDuplicated') {
                console.log('Переход на текущий маршрут проигнорирован');
            }
        });

    Ключевой момент: ошибка NavigationDuplicated не является критической и часто может игнорироваться, так как переход не приводит к нарушению логики приложения.

  2. 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 позволяет глобально перехватывать ошибки, которые возникли во время выполнения охранников.

  3. 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 предоставляет несколько способов безопасного управления ошибками:

  1. Promise-подход при push/replace

    Методы push и replace возвращают промис. Можно перехватывать ошибки, используя .catch:

    this.$router.push({ name: 'profile', params: { id: 1 } })
        .catch(err => {
            if (err.name !== 'NavigationDuplicated') {
                console.error('Ошибка перехода:', err);
            }
        });

    Важно фильтровать ошибки NavigationDuplicated, чтобы не захламлять консоль ненужными сообщениями.

  2. Глобальный обработчик onError

    router.onError(err => {
        console.error('Произошла ошибка навигации:', err);
        // Можно перенаправить пользователя на страницу ошибки
        router.push('/error');
    });

    Этот подход полезен для централизованного логирования и отображения страниц с информацией об ошибках.

  3. Обработка ошибок в навигационных охранниках

    Навигационные охранники могут возвращать ошибку вместо вызова 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('/');
});

Эти подходы совместно обеспечивают надежную обработку ошибок на всех уровнях маршрутизации: при программном переходе, через охранники и при асинхронной загрузке компонентов.