Sentry Integration Guidelines

SkillDatabases & data

Sentry error tracking and performance monitoring for React + Supabase Edge Functions. Activates when working with errors, monitoring, captureException, error boundary, error tracing, diagnostics, logger, Edge Functions, crash, failure, performance, error reporting, exception.

Use Sentry Integration Guidelines in Claude, ChatGPT or Ahel Desktop

Free. Sign in, add Sentry Integration Guidelines and connect your AI. About a minute.

Also: Claude Code · Cursor · Codex

Then ask your AI: use the Sentry Integration Guidelines skill

Details

Instructions available. Your AI can read the instructions. Execution depends on the setup they require.

Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.

Sentry Integration GuidelinesStart free

What this skill tells your AI

The instructions your AI receives, as published by aibiz-automatyzacje/claude-code-starter in .claude/skills/sentry-integration/SKILL.md and read by ahel’s review.

Kompleksowy przewodnik integracji Sentry error tracking i performance monitoring dla projektu React + Supabase Edge Functions.

Stan SDK

  • React SDK: v10+ (funkcyjne integracje, React 19 error hooks) ✅
  • Edge Functions: npm:@sentry/deno@^10 na Deno 2.x, handler export default { fetch: withSupabase(...) } ⚠️ — @sentry/deno nie ma integracji dla fetch-handlera, więc błędy łapiesz ręcznie (try/catch → captureError); ustaw defaultIntegrations: false (tak robi oficjalny przykład Supabase), używaj withScope dla izolacji i await flush() przed Response

Table of Contents

  • Critical Rules
  • Dobre praktyki (Edge Functions / Supabase)
  • Error Levels
  • Quick Reference
  • Context Enrichment
  • GDPR Compliance
  • Checklist dla Nowego Kodu
  • Common Mistakes
  • Resources

Critical Rules

  1. Nieoczekiwany błąd trafia do Sentry — wyjątek bez obsługi, awaria usługi albo błąd bazy wysyłasz przez logger.error (frontend) albo captureError (Edge Functions), bo w produkcji tylko Sentry pokazuje go operatorowi. Oczekiwana odmowa (błąd walidacji, 401, 403, 404, przekroczony limit) zostaje odpowiedzią z kodem błędu i wpisem logger.info (we froncie breadcrumb bez zdarzenia), bo zdarzenia z odmów zakrywają prawdziwe awarie.
  2. W Edge Functions błąd zapisuje await captureError(...) — helper izoluje kontekst zdarzenia (withScope) i robi flush przed odpowiedzią; sam log funkcji nie wystarcza, bo nikt go nie przegląda, a izolat może zostać zamrożony, zanim zdarzenie wyjdzie. console.* w Edge Functions stoi tylko wewnątrz helperów z _shared/ (captureError i logger — wzory w resources/edge-functions-sentry.md), bo reguły kodu wyłączają go z reszty kodu produkcyjnego.
  3. Użytkownika identyfikuje id — setSentryUser, setUser i kontekst przekazują tylko identyfikator, bez emaila i imienia, a beforeSend maskuje email, który trafi do zdarzenia mimo to (us***@example.com), bo zdarzenie widzi każdy z dostępem do projektu Sentry, a RODO wymaga minimalizacji danych.
  4. Kontekst zdarzenia to identyfikatory i nazwy operacji — hasła, tokeny, klucze API, nagłówek Authorization i ciała żądań zostają poza setContext, tagami i breadcrumbami, bo Sentry to zewnętrzny serwis i sekret wysłany tam trzeba uznać za ujawniony.
  5. Poziom odpowiada skutkowi — fatal tylko dla awarii całego systemu, error dla nieudanej operacji użytkownika, warning dla problemu odwracalnego (tabela Error Levels niżej), bo zawyżony poziom uczy operatora ignorować alerty.

Dobre praktyki (Edge Functions / Supabase)

@sentry/deno (v10) działa na Supabase Edge Runtime (Deno 2.x) ze wsparciem beforeSend. Handler piszemy jako export default { fetch: withSupabase(...) } (Deno.serve to legacy), a @sentry/deno nie ma integracji dla fetch-handlera — instrumentacja jest ręczna (try/catch). Oficjalny przykład Supabase ustawia defaultIntegrations: false na Edge Runtime, bo bez tego nie ma gwarancji scope separation między requestami w tym samym isolate. Nadal stosuj:

ZasadaDlaczego
defaultIntegrations: false w Sentry.init()Bezpieczny default dopóki nie zweryfikujesz scope separation na swoim runtime
Ustawiaj kontekst przez Sentry.withScope()Izolacja per operacja; unikasz wycieku tagów między requestami
Nie ustawiaj globalnych tagów per-requestGlobalny scope jest współdzielony w obrębie isolate'u
await Sentry.flush() przed ResponseIsolate może zostać zamrożony zaraz po odpowiedzi
Maskuj PII w beforeSendJeden centralny punkt dla wszystkich zdarzeń

Wzorzec kontekstu per request:

// ŹLE - kontekst wycieknie do innych requestów
Sentry.setTag('user_id', userId);
Sentry.captureException(error);

// DOBRZE - izolowany scope
Sentry.withScope((scope) => {
  scope.setTag('user_id', userId);
  Sentry.captureException(error);
});

Szczegóły: edge-functions-sentry.md


Error Levels

LevelKiedy używaćPrzykład
fatalSystem nie działa, wymaga natychmiastowej interwencjiBrak połączenia z bazą
errorOperacja nie powiodła się, użytkownik dotkniętyPłatność Stripe nie przeszła
warningProblem odwracalny, nie wymaga natychmiastowej akcjiRetry po timeout
infoInformacje operacyjneUżytkownik zalogowany

Quick Reference

Frontend (React)

Inicjalizacja w main.tsx:

import { initSentry } from '@/lib/sentry';
import * as Sentry from '@sentry/react';

initSentry();

ReactDOM.createRoot(document.getElementById('root')!).render(
  <Sentry.ErrorBoundary fallback={<ErrorFallback />}>
    <AppWrapper />
  </Sentry.ErrorBoundary>
);

Użycie loggera (preferowane):

import { logger } from '@/lib/logger';

try {
  await riskyOperation();
} catch (error) {
  logger.error('Operacja nie powiodła się', error);
  toast.error('Wystąpił błąd');
}

Bezpośrednie Sentry (gdy potrzeba więcej kontekstu):

import * as Sentry from '@sentry/react';

Sentry.withScope((scope) => {
  scope.setTag('operation', 'payment');
  scope.setContext('order', { orderId: '123', amount: 100 });
  Sentry.captureException(error);
});

Edge Functions (Deno)

Edge Function z Sentry i withScope:

import { withSupabase } from 'npm:@supabase/server@^1';
import { initSentry, captureError } from '../_shared/sentry.ts';

const Sentry = initSentry('function-name');

// export default { fetch } + withSupabase zamiast Deno.serve.
// Tryb auth per funkcja ('user' | 'publishable' | 'secret' | 'none');
// dla trybu innego niż 'user' -> verify_jwt = false w supabase/config.toml.
export default {
  fetch: withSupabase({ auth: 'user' }, async (req, ctx) => {
    try {
      // logika — ctx.supabase (RLS), ctx.userClaims?.id = user_id
    } catch (error) {
      // await captureError: withScope + flush wewnętrznie
      await captureError(error, {
        operation: 'checkout',
        user_id: ctx.userClaims?.id  // identyfikator, bez emaila (zasada 3)
      });
      // koperta błędu z reguł kodu; szczegóły tylko w Sentry
      return Response.json(
        { data: null, error: { code: 'INTERNAL', message: 'Operacja nie powiodła się' } },
        { status: 500 },
      );
    }
  }),
};

Context Enrichment

Kontekst błędu (tagi, kontekst operacji, breadcrumbs):

// DOBRZE - bogaty kontekst (użytkownika ustawia setSentryUser przy logowaniu)
Sentry.withScope((scope) => {
  scope.setTag('service', 'payments');
  scope.setTag('endpoint', '/checkout');
  scope.setContext('operation', {
    type: 'stripe_checkout',
    sessionId: session.id,
    amount: amount
  });
  scope.addBreadcrumb({
    category: 'payment',
    message: 'Starting checkout',
    level: 'info'
  });
  Sentry.captureException(error);
});

// ŹLE - brak kontekstu
Sentry.captureException(error); // Skąd? Co? Dla kogo?

GDPR Compliance

Użytkownik przez id, maskowanie emaila jako siatka (zasada 3):

// W beforeSend — email, który trafił do zdarzenia mimo zasady 3
beforeSend(event) {
  if (event.user?.email) {
    event.user.email = event.user.email.replace(/^(.{2}).*(@.*)$/, '$1***$2');
  }
  return event;
}

// W setSentryUser
export function setSentryUser(user: { id: string } | null) {
  if (user) {
    Sentry.setUser({ id: user.id });
  } else {
    Sentry.setUser(null);
  }
}

Checklist dla Nowego Kodu

Przed każdym PR sprawdź:

  • Zaimportowano Sentry lub odpowiedni helper
  • Każdy nieoczekiwany błąd trafia do Sentry; oczekiwane odmowy nie (zasada 1)
  • Dodano znaczący kontekst (tagi, breadcrumbs)
  • Użyto odpowiedniego poziomu błędu
  • Brak wrażliwych danych w event (hasła, tokeny)
  • Użytkownik w zdarzeniu tylko przez id; beforeSend maskuje email
  • Przetestowano ścieżki błędów

Common Mistakes

Unikaj:

// Połykanie błędów
try {
  await operation();
} catch (error) {
  // nic - użytkownik nie wie, my nie wiemy
}

// console.error bez Sentry
} catch (error) {
  console.error('Error:', error); // W produkcji nikt nie widzi!
}

// Wrażliwe dane
Sentry.setContext('auth', { token: userToken }); // token w zewnętrznym serwisie

Zamiast tego:

// Capture + informacja dla użytkownika
try {
  await operation();
} catch (error) {
  logger.error('Operacja nie powiodła się', error);
  toast.error('Wystąpił błąd. Spróbuj ponownie.');
}

// Bezpieczny kontekst
Sentry.setContext('auth', {
  userId: user.id,
  provider: 'google' // OK - nie wrażliwe
});

Resources

Szczegółowe wzorce znajdują się w:

Signals

GitHub stars
88
Forks
29
Last commit
Oct 2026

ahel review

  • K1binfo
    installs-packages (in resources/react-sentry-patterns.md)

Automated review, not a security audit. Ruleset v1+k2.

Advanced
Item type
skill
Key
sentry-integration
Source
github.com/aibiz-automatyzacje/claude-code-starter