Во фреймворке Fresh механизм обработки ошибок построен с учётом принципов современного веб-разработки на Deno и JavaScript, обеспечивая прозрачное выявление проблем на этапе разработки и минимизацию неожиданных сбоев в продакшене. В режиме development ключевое внимание уделяется детальной информации об ошибках, стек-трейсам и возможности быстрого исправления.
Fresh автоматически активирует development mode при запуске через команду:
deno task start
или при использовании переменной окружения:
DENO_ENV=development
В этом режиме включается:
Стандартная структура проекта Fresh включает папку
routes, где каждый файл определяет отдельный маршрут. Любая
ошибка в коде страницы, компонента или серверной функции будет
автоматически перехвачена и отображена с указанием точного
местоположения проблемы.
В Fresh используется концепция Error Boundaries,
аналогичная React, для изоляции ошибок на уровне компонентов. Ошибки,
возникшие в дочерних компонентах, не ломают весь маршрут, а
обрабатываются локально. Для создания Error Boundary используется
компонент с методом catch:
/** @jsx h */
import { h } from "preact";
export default function ErrorBoundary({ error }) {
return (
<div style={{ color: "red" }}>
<h1>Произошла ошибка</h1>
<pre>{error.message}</pre>
<pre>{error.stack}</pre>
</div>
);
}
Key points:
error.message выводит краткое описание
ошибки;error.stack показывает полный стек
вызовов;export const config = { errorBoundary: true };.Fresh позволяет разделять обработку ошибок на стороне сервера и
клиента. Серверные функции (handlers) могут использовать
стандартный механизм try/catch:
export const handler = {
async GET(req) {
try {
const data = await fetchSomeData();
return new Response(JSON.stringify(data));
} catch (error) {
console.error("Ошибка при загрузке данных:", error);
return new Response("Internal Server Error", { status: 500 });
}
},
};
Особенности:
500 информирует клиент о серверной
проблеме;error с подробной трассировкой прямо в ответ.Для глобальной обработки ошибок в маршрутах используется файл
_middleware.ts:
import { MiddlewareHandlerContext } from "$fresh/server.ts";
export async function handler(
req: Request,
ctx: MiddlewareHandlerContext,
) {
try {
return await ctx.next();
} catch (error) {
console.error("Глобальная ошибка маршрута:", error);
return new Response(
`<h1>Ошибка</h1><pre>${error.stack}</pre>`,
{ status: 500, headers: { "Content-Type": "text/html" } },
);
}
}
Такой подход обеспечивает:
Fresh интегрируется с deno lsp и механизмом HMR, поэтому ошибки отображаются прямо в браузере с подсветкой строк кода и стеком вызовов. Для максимально информативного вывода используется следующая структура сообщения:
Это позволяет сразу выявлять причину ошибки без необходимости заходить в консоль Deno.
try/catch только там, где есть вероятность
ошибки;console.error для
сохранения трассировки;handlers,
так как несоответствие ожидаемому формату часто является источником
ошибок.В Fresh асинхронные операции часто являются источником исключений.
При работе с fetch, базами данных или файловой системой
рекомендуется:
await внутри
try/catch;Promise с .catch() для
локальных операций;Пример асинхронного Error Boundary:
export default async function AsyncComponent() {
try {
const data = await fetchData();
return <div>{data.title}</div>;
} catch (error) {
return (
<div style={{ color: "red" }}>
<h2>Ошибка при загрузке данных</h2>
<pre>{error.stack}</pre>
</div>
);
}
}
Такой подход обеспечивает безопасное отображение ошибок без разрушения всего интерфейса.
Обработка ошибок в Fresh в режиме разработки построена на принципах прозрачности и детального контроля. Использование Error Boundaries, глобальных middleware и асинхронного перехвата исключений позволяет выявлять проблемы на раннем этапе и ускоряет процесс разработки, обеспечивая стабильность и предсказуемость поведения приложения.