Universal Router — это минималистичная и гибкая библиотека маршрутизации для JavaScript, которая позволяет создавать маршруты с асинхронными действиями и поддержкой динамических параметров. Одной из важных возможностей при работе с Universal Router является настройка глобального обработчика ошибок, который обеспечивает централизованную обработку всех исключений, возникающих при разрешении маршрутов.
В основе Universal Router лежит функция resolve, которая
принимает путь и возвращает результат выполнения соответствующего
маршрута. Любое исключение, выброшенное в action маршрута,
передаётся наверх по цепочке промисов. Для централизованной обработки
этих ошибок можно использовать глобальный обработчик, задаваемый при
создании экземпляра маршрутизатора:
import UniversalRouter from 'universal-router';
const routes = [
{ path: '/', action: () => 'Главная страница' },
{ path: '/about', action: () => { throw new Error('Ошибка при загрузке /about'); } },
];
const router = new UniversalRouter(routes, {
resolveRoute(context, params) {
try {
return UniversalRouter.resolve.call(this, context, params);
} catch (err) {
return handleGlobalError(err, context, params);
}
}
});
function handleGlobalError(error, context, params) {
console.error('Глобальная ошибка маршрута:', error.message);
return 'Страница с ошибкой';
}
В этом примере функция resolveRoute выступает в роли
обёртки над стандартным методом resolve, перехватывая все
ошибки и передавая их в handleGlobalError. Это позволяет
централизованно логировать ошибки, показывать пользователю страницу с
сообщением об ошибке или выполнять другие действия.
try/catch в actionКаждый маршрут может содержать асинхронные действия, и ошибки могут
возникать как синхронно, так и асинхронно. Universal Router поддерживает
промисы, поэтому обработка ошибок через try/catch должна
учитывать асинхронность:
const routes = [
{
path: '/data',
async action() {
try {
const response = await fetch('/api/data');
if (!response.ok) throw new Error('Ошибка при загрузке данных');
return await response.json();
} catch (err) {
throw err; // ошибка будет перехвачена глобальным обработчиком
}
}
}
];
Даже если ошибка выбрасывается внутри асинхронной функции, глобальный обработчик, описанный выше, сможет её перехватить.
Иногда требуется специфическая обработка ошибок на уровне отдельного маршрута, при этом глобальный обработчик остаётся «запасным»:
const routes = [
{
path: '/profile',
async action() {
try {
return await fetchUserProfile();
} catch (err) {
console.warn('Ошибка загрузки профиля, возвращаем дефолтные данные');
return { name: 'Гость' };
}
}
}
];
В этом случае, если ошибка произойдет только в этом маршруте, она будет обработана локально, а глобальный обработчик сработает только для других маршрутов.
Глобальный обработчик может быть асинхронным. Это полезно, если требуется выполнить, например, логирование на сервер или асинхронную переадресацию:
async function handleGlobalError(error, context) {
await sendErrorLogToServer(error, context.path);
return { redirect: '/error' };
}
resolve корректно обработает промис, возвращённый
обработчиком, и можно использовать результат для дальнейшей логики
маршрутизации.
Universal Router передаёт в обработчик ошибки контекст маршрута, что позволяет получать информацию о текущем пути, параметрах и родительских маршрутах:
function handleGlobalError(error, context) {
console.error(`Ошибка на пути ${context.path}`);
console.error('Параметры:', context.params);
return 'Произошла ошибка';
}
Такой подход позволяет строить гибкую систему логирования и уведомлений.
try/catch, так как
часть ошибок может быть пропущена.Грамотная настройка глобального обработчика ошибок в Universal Router позволяет строить надёжные и предсказуемые маршруты, минимизируя риск неконтролируемых исключений и обеспечивая единообразное поведение приложения при ошибках.