Ir al contenido

Sentry

CÉNIT usa Sentry para captura de errores y observabilidad en los tres runtimes de Next.js: client, server y edge. Cada runtime tiene su config separada (sentry.client.config.ts, sentry.server.config.ts, sentry.edge.config.ts). En producción, el server y edge runtime corren bajo Cloudflare Workers — donde @sentry/cloudflare toma el control vía worker-entry.ts y los init de @sentry/nextjs quedan deshabilitados para evitar doble captura.

  • DSN: NEXT_PUBLIC_SENTRY_DSN.
  • tracesSampleRate: 100% en dev, 10% en prod.
  • replaysOnErrorSampleRate: 50% en prod (replays con maskAllText: true y blockAllMedia: true para no exponer datos sensibles).
  • replaysSessionSampleRate: 0 — no se graban sesiones sanas.
  • DSN: SENTRY_DSN (sin prefijo NEXT_PUBLIC_).
  • tracesSampleRate: 10% en prod.
  • Skip si NEXT_RUNTIME === 'cloudflare'@sentry/cloudflare ya está activo en ese entorno; init doble dispararía eventos duplicados.
  • DSN: SENTRY_DSN.
  • tracesSampleRate: 50% en prod.
  • Mismo skip por NEXT_RUNTIME === 'cloudflare'.

beforeSend() filtra campos sensibles del payload antes de enviar el evento a Sentry. Lista actual (client + server):

  • Auth: password, confirm, token, api_key, secret, service_role_key.
  • Clínica: diagnosis, notes, mental_notes, injury_type, body_part.
  • Wellness: muscle_soreness, fatigue, stress, sleep_quality, rpe, hooper_index.

Cualquier match se reemplaza por [Filtered]. Esto es defense in depth — el origen de la PII debería estar en server actions, donde el payload del request no debería incluir estos campos en form-data.

Cada evento se taggea con el commit SHA del build:

  • Client: NEXT_PUBLIC_GITHUB_SHA (inlineada en el bundle).
  • Server / edge: GITHUB_SHA.

CI (cloudflare-deploy.yml) exporta estas vars en el env: del job de build, así Sentry vincula cada evento al deploy exacto. En local quedan undefined y los eventos no se tagan.

En producción los tag pushes (v*) crean releases nombradas con el tag; los deploys de staging usan el SHA del commit.

Sentry.withScope(scope => {
scope.setTag('email_to', to)
scope.setExtra('resend_status', res.status)
scope.setLevel('error')
Sentry.captureException(new Error('Resend API error'))
})

Ver lib/send-email.ts y app/api/stripe/webhook/route.ts para ejemplos canónicos.

Convención de tags útiles: route: stripe/webhook, event: checkout.session.completed, eventId: evt_xxx, email_to, customerId. Permiten filtrar incidentes rápido en el dashboard.

Ventana de terminal
NEXT_PUBLIC_SENTRY_DSN=
SENTRY_DSN=
NEXT_PUBLIC_GITHUB_SHA= # CI
GITHUB_SHA= # CI
SENTRY_AUTH_TOKEN= # solo para upload de sourcemaps en build
  • Email (Resend)sendEmail captura errores de Resend con tags.
  • Plans y billing — el webhook de Stripe captura todo error de procesamiento.
  • CI/CD — el SHA del build se inyecta como release.
  • Error digests de Next.js 16 en producción — Next reemplaza los mensajes del server por un código digest (XXXXXXXX@EX). Para debuggear el mensaje real hay que ir a Sentry (donde sí queda loggeado) o a los logs de Workers (wrangler tail).
  • Replays a 50% en prod — alto, pero útil mientras estamos descubriendo bugs de UI. Bajar a 20-30% una vez estable.
  • Lista de scrubbing manual — agregar campos clínicos nuevos al array de SCRUB cuando aparezcan en formularios futuros.