Обработка ошибок загрузки

Navigo — легковесный роутер для JavaScript, ориентированный на клиентские одностраничные приложения (SPA). Одним из важных аспектов работы с Navigo является корректная обработка ошибок при загрузке ресурсов или при неправильных маршрутах, чтобы приложение не зависало и обеспечивало предсказуемое поведение.


Обработка маршрутов, которых нет

Navigo позволяет задавать маршруты с помощью метода on. Если пользователь переходит по URL, который не соответствует ни одному из зарегистрированных маршрутов, необходимо предусмотреть обработку таких случаев через метод notFound.

const router = new Navigo('/');

router.on('/home', () => {
    console.log('Главная страница');
});

router.on('/about', () => {
    console.log('О нас');
});

router.notFound(() => {
    console.error('Страница не найдена');
});

Ключевой момент: notFound вызывается автоматически для любого URL, который не совпадает с зарегистрированными маршрутами, что позволяет централизованно обрабатывать ошибки 404 на клиентской стороне.


Асинхронная загрузка данных и обработка ошибок

В SPA часто требуется загружать данные с сервера при переходе на определённый маршрут. Navigo позволяет использовать асинхронные функции внутри обработчиков маршрутов, что даёт возможность ловить ошибки через try/catch или промисы.

router.on('/profile/:id', async ({ data }) => {
    try {
        const response = await fetch(`/api/users/${data.id}`);
        if (!response.ok) throw new Error('Ошибка загрузки данных пользователя');
        const user = await response.json();
        renderProfile(user);
    } catch (error) {
        console.error(error.message);
        renderError('Не удалось загрузить данные профиля');
    }
});

Важные моменты:

  • Проверка response.ok позволяет отловить HTTP-ошибки (например, 404 или 500).
  • Использование try/catch обеспечивает обработку исключений, возникающих при сетевых ошибках или при разборе JSON.
  • Централизованная функция renderError позволяет отображать пользователю понятное сообщение вместо необработанной ошибки.

Перехват ошибок навигации

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

try {
    router.resolve();
} catch (err) {
    console.error('Ошибка при навигации:', err);
    showNavigationError();
}

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


Универсальный обработчик ошибок

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

function handleRouteError(error, route) {
    console.error(`Ошибка при загрузке маршрута ${route}:`, error);
    displayErrorMessage('Произошла ошибка при загрузке страницы');
}

// Пример использования в маршрутах
router.on('/dashboard', async () => {
    try {
        await loadDashboard();
    } catch (err) {
        handleRouteError(err, '/dashboard');
    }
});

Преимущества такого подхода:

  • Централизованная обработка ошибок упрощает поддержку кода.
  • Легко интегрировать с системами логирования или аналитики.
  • Упрощает тестирование и улучшает UX, показывая пользователю предсказуемые сообщения вместо необработанных исключений.

Обработка ошибок при динамических маршрутах

Navigo поддерживает динамические сегменты (:param). Ошибки могут возникать при некорректных значениях параметров. Рекомендуется проверять параметры и при необходимости перенаправлять пользователя на страницу ошибки.

router.on('/product/:productId', ({ data }) => {
    const productId = parseInt(data.productId, 10);
    if (isNaN(productId)) {
        router.navigate('/error');
        return;
    }
    fetchProductDetails(productId)
        .then(renderProduct)
        .catch(err => handleRouteError(err, `/product/${productId}`));
});

Особенности:

  • Преобразование параметров и валидация позволяют избежать ошибок при работе с серверными данными.
  • Перенаправление на страницу ошибки через router.navigate улучшает UX.
  • Обработка промисов позволяет ловить сетевые и логические ошибки одновременно.

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

  • Использовать console.error для разработки, но на продакшене лучше интегрировать централизованную систему логирования.
  • Хранить контекст ошибки: URL маршрута, параметры, статус ответа сервера.
  • В случаях асинхронных ошибок хранить stack trace и сообщение, чтобы ускорить отладку.

Итоговая структура обработки ошибок

  1. Маршруты не найдены: метод notFound.
  2. Ошибки асинхронной загрузки данных: try/catch внутри обработчика маршрута.
  3. Ошибки навигации: обертка вокруг router.resolve().
  4. Динамические маршруты: валидация параметров и перенаправление на страницу ошибки.
  5. Централизованное логирование: универсальный обработчик handleRouteError.

Эта система обеспечивает предсказуемое поведение SPA, предотвращает падения при некорректных URL и сетевых сбоях, и позволяет поддерживать приложение в стабильном состоянии при любых ошибках загрузки.