Логирование ошибок навигации

Общие сведения о навигационных ошибках

В Vue Router любые попытки перехода между маршрутами могут приводить к ошибкам. Типичными случаями являются: переход на тот же маршрут с идентичными параметрами, недопустимые параметры маршрута, отказ в доступе из-за навигационных охранников. В версии Vue Router 4 введена унифицированная система обработки таких ошибок с помощью объектов ошибок навигации (NavigationFailure).

Ошибки навигации классифицируются следующим образом:

  • NavigationFailureType.cancelled — переход был отменён другим переходом.
  • NavigationFailureType.duplicated — попытка перехода на текущий маршрут с теми же параметрами.
  • NavigationFailureType.redirected — переход был перенаправлен на другой маршрут.
  • NavigationFailureType.aborted — переход прерван навигационными охранниками.

Эти типы позволяют точно идентифицировать причины неудачной навигации и применять соответствующую обработку.


Методы логирования ошибок

Использование глобального обработчика

Vue Router предоставляет возможность глобальной перехватки ошибок через метод router.onError. Это позволяет централизованно логировать все ошибки навигации:

import { createRouter, createWebHistory } from 'vue-router';

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

router.onError((error) => {
  console.error('Произошла ошибка навигации:', error);
});

onError срабатывает при любых непойманных исключениях, возникающих в процессе перехода, включая ошибки асинхронных компонентов.


Проверка типа ошибки

Для фильтрации типов навигационных ошибок используется функция isNavigationFailure:

import { isNavigationFailure, NavigationFailureType } from 'vue-router';

router.push('/current-route').catch((err) => {
  if (isNavigationFailure(err, NavigationFailureType.duplicated)) {
    console.warn('Дублирующий переход:', err);
  } else {
    console.error('Ошибка навигации:', err);
  }
});

Это позволяет отличать обычные ошибки навигации от программных исключений и реагировать на них по-разному.


Логирование с асинхронными маршрутами

Для маршрутов с ленивой загрузкой компонентов важно логировать ошибки загрузки модулей:

const routes = [
  {
    path: '/dashboard',
    component: () => import('./components/Dashboard.vue'),
  },
];

router.beforeEach((to, from, next) => {
  next();
});

router.onError((err) => {
  if (err.message.includes('Failed to fetch dynamically imported module')) {
    console.error('Ошибка загрузки модуля:', err);
  } else {
    console.error('Неизвестная ошибка навигации:', err);
  }
});

Такой подход позволяет выявлять ошибки сетевого характера и некорректные пути динамического импорта.


Логирование ошибок в навигационных охранниках

Ошибки могут возникать как внутри глобальных, так и локальных охранников маршрута (beforeEach, beforeResolve, beforeEnter). Для их перехвата необходимо использовать блоки try/catch или возвращаемые промисы:

router.beforeEach(async (to, from, next) => {
  try {
    const authorized = await checkUserAuthorization();
    if (!authorized) {
      next('/login');
    } else {
      next();
    }
  } catch (err) {
    console.error('Ошибка в навигационном охраннике:', err);
    next(false); // отменяем навигацию
  }
});

Использование next(false) предотвращает переход при ошибках, сохраняя стабильность приложения.


Интеграция с системами логирования

Для крупных приложений удобно интегрировать логирование ошибок навигации с внешними сервисами (Sentry, LogRocket, Datadog):

router.onError((err) => {
  Sentry.captureException(err);
  console.error('Ошибка навигации зафиксирована в Sentry:', err);
});

Такой подход обеспечивает централизованный сбор информации об ошибках и упрощает анализ нестандартных сценариев поведения.


Логирование на уровне компонентов

Компоненты могут самостоятельно реагировать на ошибки навигации при использовании программного перехода через router.push или router.replace:

export default {
  methods: {
    goToProfile() {
      this.$router.push('/profile').catch((err) => {
        if (!isNavigationFailure(err, NavigationFailureType.duplicated)) {
          console.error('Ошибка перехода к профилю:', err);
        }
      });
    }
  }
};

Фильтрация дублирующих переходов предотвращает лишние предупреждения в консоли и упрощает поддержку кода.


Рекомендации по практическому логированию

  • Всегда проверять тип ошибки с помощью isNavigationFailure.
  • Использовать router.onError для глобальной перехватки ошибок.
  • Логировать ошибки асинхронных модулей отдельно.
  • Обрабатывать ошибки навигационных охранников через try/catch.
  • Интегрировать с внешними системами мониторинга для анализа и уведомлений.
  • Фильтровать дублирующие переходы, чтобы не засорять консоль лишними логами.

Правильная организация логирования ошибок навигации обеспечивает стабильность приложения, прозрачность переходов и удобство отладки сложных сценариев маршрутизации.