В Riot.js маршрутизация осуществляется с помощью встроенного роутера, который связывает URL-приложения с компонентами. Основная задача роутера — корректно отобразить нужный компонент при изменении адреса, однако в реальных приложениях невозможно исключить ситуации, когда путь не существует или возникает ошибка при загрузке компонента. Управление такими ошибками критически важно для поддержания стабильной работы интерфейса.
Riot.js использует простой, но гибкий роутер, который позволяет задавать маршруты с привязкой к компонентам:
import { component, route } from 'riot';
route('/home', 'home-component');
route('/profile/:id', 'profile-component');
route('*', 'notfound-component'); // wildcard для несуществующих маршрутов
Каждый маршрут привязывается к имени компонента. Wildcard
* используется для обработки случаев, когда путь не совпал
ни с одним из определённых маршрутов. Это первый шаг к обработке ошибок:
любое неизвестное направление можно перенаправить на компонент с
уведомлением о недоступности страницы.
Riot.js роутер позволяет определить глобальный обработчик ошибок
через событие onRouteError. Этот метод вызывается, если
загрузка компонента завершилась неудачей:
route.on('routeError', (error, path) => {
console.error(`Ошибка маршрутизации для пути ${path}:`, error);
route('/error'); // перенаправление на страницу с ошибкой
});
Ключевой момент: error содержит объект
ошибки, что позволяет логировать её или отправлять на сервер для
анализа. path — путь, на котором произошла ошибка.
В крупных приложениях часто используется динамический импорт компонентов для оптимизации загрузки. В таких случаях важно обрабатывать ошибки асинхронно:
route('/dashboard', async () => {
try {
const module = await import('./components/dashboard-component.js');
return module.default;
} catch (e) {
console.error('Не удалось загрузить компонент Dashboard:', e);
return import('./components/error-component.js');
}
});
Здесь применяется try-catch, который позволяет
предотвратить падение всего приложения и заменить неудачно загруженный
компонент на запасной.
Помимо глобального перенаправления, можно создавать специальные fallback-компоненты для конкретных маршрутов:
route('/settings', async () => {
try {
const module = await import('./components/settings-component.js');
return module.default;
} catch {
return import('./components/settings-fallback.js');
}
});
Это обеспечивает локальную обработку ошибок без глобального вмешательства, повышая устойчивость отдельных участков интерфейса.
Для поддержки стабильности приложения рекомендуется внедрять централизованное логирование ошибок маршрутизации. Пример:
route.on('routeError', (error, path) => {
fetch('/api/log', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ path, message: error.message, stack: error.stack })
});
route('/error');
});
Таким образом, каждая ошибка фиксируется и может быть проанализирована без воздействия на пользовательский опыт.
Ошибки маршрутизации часто требуют взаимодействия со состоянием приложения. Например, при несанкционированном доступе к защищённому маршруту:
route('/admin', () => {
if (!store.user.isAdmin) {
route('/forbidden');
return;
}
return import('./components/admin-component.js');
});
Здесь проверка роли пользователя позволяет предотвратить загрузку компонента, а пользователю предоставляется понятная информация о недоступности страницы.
try-catch.Такой подход позволяет строить надёжную систему маршрутизации, минимизируя вероятность аварийного поведения интерфейса при ошибках и недоступных компонентах.