Aller au contenu principal

Sentry Error Tracking

Sentry is configured for error tracking and performance monitoring in both the backend (NestJS) and frontend (React).

Configuration

Environment Variables

Add these variables to your .env file:

# Backend Sentry DSN
SENTRY_DSN=https://your-key@sentry.io/your-project-id

# Frontend Sentry DSN (same or different project)
VITE_SENTRY_DSN=https://your-key@sentry.io/your-project-id

# Optional: Release version (auto-set to git commit SHA in CI)
SENTRY_RELEASE=1.0.0

Getting Your DSN

  1. Go to Sentry.io and create an account
  2. Create a new project for NestJS (backend)
  3. Create a new project for React (frontend) - or use the same project
  4. Copy the DSN from Project Settings > Client Keys (DSN)

Features

Backend (NestJS)

  • Global Exception Filter: All 5xx errors are automatically captured
  • User Context: Logged-in user ID and email are attached to errors
  • Request Context: URL, method, and request body are captured
  • Unhandled Exceptions: uncaughtException and unhandledRejection are captured
  • Worker Support: Both API and Worker processes report errors

Filtered Errors

The following errors are NOT sent to Sentry:

  • 4xx client errors (bad request, unauthorized, etc.)

Frontend (React)

  • Automatic Error Capture: JavaScript errors are captured automatically
  • User Context: User ID and email are attached when logged in
  • Performance Monitoring: Page load and API calls are traced
  • Session Replay: Available for debugging (10% of sessions, 100% on error)

Filtered Errors

The following errors are NOT sent to Sentry:

  • Network errors ("Failed to fetch")
  • ResizeObserver errors (browser quirk)

Usage

Backend - Manual Error Capture

import * as Sentry from "@sentry/node";

// Capture an exception
Sentry.captureException(error);

// Capture with extra context
Sentry.withScope((scope) => {
scope.setTag("feature", "payment");
scope.setExtra("orderId", orderId);
Sentry.captureException(error);
});

// Capture a message
Sentry.captureMessage("Something happened", "warning");

Frontend - Manual Error Capture

import { captureException, captureMessage } from "@/lib/sentry";

// Capture an exception
captureException(error, { context: "payment" });

// Capture a message
captureMessage("User performed action", "info");

Frontend - Error Boundary

import { ErrorBoundary } from "@/lib/sentry";

function MyComponent() {
return (
<ErrorBoundary fallback={<p>An error occurred</p>}>
<ChildComponent />
</ErrorBoundary>
);
}

CI/CD Integration

The GitLab CI pipeline automatically:

  1. Passes VITE_SENTRY_DSN to the frontend build
  2. Sets SENTRY_RELEASE to the git commit SHA
  3. Configures both API and Worker containers with Sentry

Required GitLab CI Variables

Add these variables in GitLab > Settings > CI/CD > Variables:

VariableDescription
SENTRY_DSNBackend Sentry DSN
VITE_SENTRY_DSNFrontend Sentry DSN

Architecture

┌─────────────────────────────────────────────────────────┐
│ Sentry.io │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Backend Project │ │ Frontend Project │ │
│ └────────▲────────┘ └────────▲────────┘ │
└───────────┼──────────────────────┼──────────────────────┘
│ │
┌───────┴───────┐ ┌───────┴───────┐
│ Backend │ │ Frontend │
│ (NestJS) │ │ (React) │
│ │ │ │
│ • API Server │ │ • Web App │
│ • Worker │ │ │
└───────────────┘ └───────────────┘

Troubleshooting

Errors Not Appearing in Sentry

  1. Check that SENTRY_DSN / VITE_SENTRY_DSN is set correctly
  2. Verify the DSN format: https://<key>@<org>.ingest.sentry.io/<project-id>
  3. Check console for "Sentry initialized" message
  4. Ensure you're not filtering the error (see Filtered Errors above)

Performance Issues

If Sentry impacts performance, adjust the sample rates:

// Backend: sentry.module.ts
tracesSampleRate: 0.05, // 5% of transactions

// Frontend: sentry.ts
tracesSampleRate: 0.05,
replaysSessionSampleRate: 0.01, // 1% of sessions

Mobile App Integration

For the mobile app (aaperture-mobile), use @sentry/react-native:

import * as Sentry from "@sentry/react-native";

Sentry.init({
dsn: "YOUR_MOBILE_SENTRY_DSN",
environment: __DEV__ ? "development" : "production",
});