Sentry интеграция

Общие принципы интеграции

Fresh — это современный веб-фреймворк для JavaScript и Deno, ориентированный на высокую производительность и минимальный runtime. Встроенная реактивность и серверная рендеринг-ориентированная архитектура требуют особого подхода к мониторингу ошибок. Sentry позволяет централизованно отслеживать исключения и события, происходящие как на клиентской, так и на серверной части приложения.

Основная цель интеграции Sentry с Fresh — получение полного стека ошибок, включая серверные и клиентские исключения, без существенного влияния на производительность.

Установка Sentry

Для Fresh проект на Deno интеграция выполняется через официальный пакет @sentry/browser для клиента и @sentry/node для серверной части. Установка происходит через deno.land:

deno install --allow-net --allow-read https://deno.land/x/sentry

или подключение через импорты модулей в коде:

import * as Sentry from "https://cdn.skypack.dev/@sentry/browser";
import * as SentryNode from "https://cdn.skypack.dev/@sentry/node";

Инициализация Sentry

Для серверной части Fresh важно корректно инициализировать Sentry на этапе старта приложения. Пример:

// server.ts
import * as SentryNode from "@sentry/node";

SentryNode.init({
  dsn: "https://<PUBLIC_KEY>@sentry.io/<PROJECT_ID>",
  tracesSampleRate: 1.0, // отслеживание производительности
});

Для клиентской части:

// client.ts
import * as Sentry from "@sentry/browser";

Sentry.init({
  dsn: "https://<PUBLIC_KEY>@sentry.io/<PROJECT_ID>",
  integrations: [new Sentry.BrowserTracing()],
  tracesSampleRate: 1.0,
});

Ключевой момент: tracesSampleRate определяет частоту отслеживания производительности. Для продакшена обычно ставят 0.1–0.25, чтобы не перегружать Sentry.

Обработка ошибок на сервере

Fresh использует функции-обработчики запросов (Handler), которые возвращают Response. Для интеграции Sentry ошибки можно обрабатывать через middleware-подход:

import { HandlerContext } from "$fresh/server.ts";

export const handler = async (req: Request, ctx: HandlerContext) => {
  try {
    return await ctx.next();
  } catch (err) {
    SentryNode.captureException(err);
    return new Response("Internal Server Error", { status: 500 });
  }
};

Этот подход гарантирует, что все исключения, возникающие в middleware и роутерах, будут зафиксированы в Sentry.

Обработка ошибок на клиенте

На клиентской стороне важно ловить не только исключения из кода, но и глобальные ошибки браузера:

window.addEventListener("error", (event) => {
  Sentry.captureException(event.error);
});

window.addEventListener("unhandledrejection", (event) => {
  Sentry.captureException(event.reason);
});

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

Интеграция с компонентами Fresh

Fresh использует серверный рендеринг компонентов, поэтому ошибки внутри компонент можно обрабатывать с помощью try/catch и отправки их в Sentry:

export default function Page(props: any) {
  try {
    // основной JSX/HTML
    return <div>{props.content}</div>;
  } catch (err) {
    Sentry.captureException(err);
    return <div>Произошла ошибка</div>;
  }
}

Для глобальной обработки ошибок компонентов можно создать HOC (Higher-Order Component), который оборачивает все страницы или отдельные важные компоненты.

Трассировка производительности

Sentry поддерживает трассировку производительности через BrowserTracing на клиенте и Performance на сервере. В Fresh это позволяет отслеживать время рендеринга страниц и выполнения обработчиков запросов:

Sentry.startTransaction({ name: "page_load", op: "navigation" });

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

Отправка пользовательских событий

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

Sentry.captureMessage("Пользовательский лог", "info");
Sentry.captureEvent({
  message: "Событие приложения",
  level: "warning",
  extra: { userId: 123, action: "click" },
});

Это полезно для анализа логики приложения, которая не приводит к исключению, но требует внимания.

Рекомендации по производительности

  • Использовать минимальный tracesSampleRate на продакшене.
  • Не отправлять слишком объёмные объекты в extra или tags.
  • Ловить только реальные ошибки, не дублировать события.
  • На сервере оборачивать критичные участки кода в try/catch с отправкой в Sentry.

Совместимость с Deno Deploy

Fresh часто разворачивается на Deno Deploy, где ограничения на runtime требуют лёгких интеграций. Sentry можно использовать без изменений, но стоит учитывать, что асинхронная отправка событий не блокирует обработку запроса, поэтому нет риска задержки ответа клиенту.

Настройка окружений

Sentry поддерживает различные среды (environment) для разграничения ошибок в development, staging и production:

Sentry.init({
  dsn: "https://<PUBLIC_KEY>@sentry.io/<PROJECT_ID>",
  environment: Deno.env.get("ENVIRONMENT") || "development",
});

Использование environment позволяет фильтровать тестовые ошибки и концентрироваться на продакшн-инцидентах.