Page.js — это легковесная клиентская маршрутизирующая библиотека для JavaScript, которая позволяет управлять переходами между страницами без перезагрузки браузера. Несмотря на простоту использования, при работе с маршрутизатором могут возникать ошибки, связанные с некорректной маршрутизацией, неправильной обработкой URL или проблемами асинхронного кода. Для эффективного отлавливания таких ошибок используется логирование.
Логирование ошибок в Page.js играет ключевую роль при отладке сложных приложений и помогает выявлять источники проблем, не прерывая работу всего приложения.
Page.js предоставляет возможность определить глобальный обработчик
ошибок через функцию page('*', callback), которая
перехватывает все маршруты. Для логирования ошибок обычно используют
блоки try...catch внутри обработчиков:
page('*', (ctx, next) => {
try {
next();
} catch (error) {
console.error('Ошибка в маршруте:', ctx.path, error);
}
});
Пояснение:
ctx.path — текущий путь маршрута, где произошла
ошибка.next() — передает управление следующему обработчику
маршрута.console.error — выводит подробную информацию об ошибке
в консоль.Такой подход позволяет фиксировать не только саму ошибку, но и контекст её возникновения.
Каждый маршрут Page.js может иметь несколько обработчиков. Для
обеспечения безопасного выполнения и прозрачного логирования ошибок
рекомендуется оборачивать логику маршрута в
try...catch:
page('/dashboard', async (ctx, next) => {
try {
const data = await fetchData();
renderDashboard(data);
} catch (error) {
console.error(`Ошибка при загрузке Dashboard по пути ${ctx.path}:`, error);
}
});
Ключевые моменты:
try...catch, иначе ошибки могут остаться
незамеченными.ctx содержит полезную информацию:
параметры (ctx.params), путь (ctx.path),
query-параметры (ctx.querystring).Для крупных приложений полезно различать ошибки по категориям:
try {
const response = await fetch('/api/data');
if (!response.ok) throw new Error(`Сервер вернул статус ${response.status}`);
} catch (error) {
console.error('Ошибка сетевого запроса:', error);
}
try {
renderComponent(data);
} catch (error) {
console.error('Ошибка рендеринга компонента:', error);
}
page('*', (ctx, next) => {
try {
next();
} catch (error) {
console.error('Ошибка маршрутизации на пути', ctx.path, error);
}
});
Разделение ошибок позволяет быстро определить, на каком уровне возникла проблема — сервер, UI или маршрутизация.
Помимо console.error, можно подключать сторонние сервисы
логирования, например, Sentry или LogRocket:
page('*', (ctx, next) => {
try {
next();
} catch (error) {
Sentry.captureException(error, {
extra: { path: ctx.path, params: ctx.params }
});
console.error('Ошибка маршрута отправлена в Sentry:', ctx.path, error);
}
});
Преимущества:
Page.js поддерживает несколько middleware, вызываемых последовательно. В асинхронных цепочках важно корректно обрабатывать ошибки:
page('/profile', loadUserData, renderProfile);
async function loadUserData(ctx, next) {
try {
ctx.user = await fetchUser(ctx.params.id);
await next();
} catch (error) {
console.error('Ошибка загрузки данных пользователя:', ctx.params.id, error);
}
}
function renderProfile(ctx) {
try {
displayProfile(ctx.user);
} catch (error) {
console.error('Ошибка отображения профиля:', error);
}
}
Рекомендации:
try...catch.Для удобства чтения логов можно использовать структурированные объекты вместо простых строк:
console.error({
type: 'RoutingError',
path: ctx.path,
params: ctx.params,
message: error.message,
stack: error.stack
});
Преимущества такого подхода:
Иногда ошибки могут происходить не в обработчиках, а при самой навигации Page.js:
page('*', (ctx, next) => {
try {
if (!isValidPath(ctx.path)) throw new Error('Недопустимый путь');
next();
} catch (error) {
console.error('Ошибка навигации:', ctx.path, error);
}
});
Контроль за корректностью URL и параметров маршрута предотвращает неожиданные сбои при переходах.
try...catch.Такая организация логирования позволяет Page.js работать стабильно, а разработчикам — быстро идентифицировать и исправлять ошибки без ущерба для пользовательского опыта.