Skip to main content

sentry-nestjs-sdk

Full Sentry SDK setup for NestJS. Use when asked to "add Sentry to NestJS", "install @sentry/nestjs", "setup Sentry in NestJS", or configure error monitoring, tracing, profiling, logging, metrics, crons, or AI monitoring for NestJS applications. Supports Express and Fastify adapters, GraphQL, microservices, WebSockets, and background jobs.

Source facts

Repository
getsentry/sentry-for-ai
Last source activity
July 10, 2026 at 15:51
Detected SKILL.md language
English
Stars
268
Forks
35

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
8 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
sentry-nestjs-sdk
description
Full Sentry SDK setup for NestJS. Use when asked to "add Sentry to NestJS", "install @sentry/nestjs", "setup Sentry in NestJS", or configure error monitoring, tracing, profiling, logging, metrics, crons, or AI monitoring for NestJS applications. Supports Express and Fastify adapters, GraphQL, microservices, WebSockets, and background jobs.
license
Apache-2.0
category
sdk-setup
parent
sentry-sdk-setup
disable-model-invocation
true
> [All Skills](../../SKILL_TREE.md) > [SDK Setup](../sentry-sdk-setup/SKILL.md) > NestJS SDK # Sentry NestJS SDK Opinionated wizard that scans your NestJS project and guides you through complete Sentry setup. ## Invoke This Skill When - User asks to "add Sentry to NestJS" or "setup Sentry" in a NestJS app - User wants error monitoring, tracing, profiling, logging, metrics, or crons in NestJS - User mentions `@sentry/nestjs` or Sentry + NestJS - User wants to monitor NestJS controllers, services, guards, microservices, or background jobs > **Note:** SDK versions and APIs below reflect `@sentry/nestjs` 10.x (NestJS 8–11 supported). > Always verify against [docs.sentry.io/platforms/node/guides/nestjs/](https://docs.sentry.io/platforms/node/guides/nestjs/) before implementing. --- ## Phase 1: Detect Run these commands to understand the project before making recommendations: ```bash # Confirm NestJS project grep -E '"@nestjs/core"' package.json 2>/dev/null # Check NestJS version node -e "console.log(require('./node_modules/@nestjs/core/package.json').version)" 2>/dev/null # Check existing Sentry grep -i sentry package.json 2>/dev/null ls src/instrument.ts 2>/dev/null grep -r "Sentry.init\|@sentry" src/main.ts src/instrument.ts 2>/dev/null # Check for existing Sentry DI wrapper (common in enterprise NestJS) grep -rE "SENTRY.*TOKEN|SentryProxy|SentryService" src/ libs/ 2>/dev/null # Check for config-class-based init (vs env-var-based) grep -rE "class SentryConfig|SentryConfig" src/ libs/ 2>/dev/null # Check if SentryModule.forRoot() is already registered in a shared module grep -rE "SentryModule\.forRoot|SentryProxyModule" src/ libs/ 2>/dev/null # Detect HTTP adapter (default is Express) grep -E "FastifyAdapter|@nestjs/platform-fastify" package.json src/main.ts 2>/dev/null # Detect GraphQL grep -E '"@nestjs/graphql"|"apollo-server"' package.json 2>/dev/null # Detect microservices grep '"@nestjs/microservices"' package.json 2>/dev/null # Detect WebSockets grep -E '"@nestjs/websockets"|"socket.io"' package.json 2>/dev/null # Detect task queues / scheduled jobs grep -E '"@nestjs/bull"|"@nestjs/bullmq"|"@nestjs/schedule"|"bullmq"|"bull"' package.json 2>/dev/null # Detect databases grep -E '"@prisma/client"|"typeorm"|"mongoose"|"pg"|"mysql2"' package.json 2>/dev/null # Detect AI libraries grep -E '"openai"|"@anthropic-ai"|"langchain"|"@langchain"|"@google/generative-ai"|"ai"' package.json 2>/dev/null # Check for companion frontend ls -d ../frontend ../web ../client ../ui 2>/dev/null ``` **What to note:** - Is `@sentry/nestjs` already installed? If yes, check if `instrument.ts` exists and `Sentry.init()` is called — may just need feature config. - **Sentry DI wrapper detected?** → The project wraps Sentry behind a DI token (e.g. `SENTRY_PROXY_TOKEN`) for testability. Use the injected proxy for all runtime Sentry calls (`startSpan`, `captureException`, `withIsolationScope`) instead of importing `@sentry/nestjs` directly in controllers, services, and processors. Only `instrument.ts` should import `@sentry/nestjs` directly. - **Config class detected?** → The project uses a typed config class for `Sentry.init()` options (e.g. loaded from YAML or `@nestjs/config`). Any new SDK options must be added to the config type — do not hardcode values that should be configurable per environment. - **`SentryModule.forRoot()` already registered?** → If it's in a shared module (e.g. a Sentry proxy module), do not add it again in `AppModule` — this causes duplicate interceptor registration. - Express (default) or Fastify adapter? Express is fully supported; Fastify works but has known edge cases. - GraphQL detected? → `SentryGlobalFilter` handles it natively. - Microservices detected? → Recommend RPC exception filter. - Task queues / `@nestjs/schedule`? → Recommend crons. - AI libraries? → Auto-instrumented, zero config. - Prisma? → Requires manual `prismaIntegration()`. - Companion frontend? → Triggers Phase 4 cross-link. --- ## Phase 2: Recommend Based on what you found, present a concrete proposal. Don't ask open-ended questions — lead with a recommendation: **Always recommended (core coverage):** - ✅ **Error Monitoring** — captures unhandled exceptions across HTTP, GraphQL, RPC, and WebSocket contexts - ✅ **Tracing** — auto-instruments middleware, guards, pipes, interceptors, filters, and route handlers **Recommend when detected:** - ✅ **Profiling** — production apps where CPU performance matters (`@sentry/profiling-node`) - ✅ **Logging** — structured Sentry Logs + optional console capture - ✅ **Crons** — `@nestjs/schedule`, Bull, or BullMQ detected - ✅ **Metrics** — business KPIs or SLO tracking - ✅ **AI Monitoring** — OpenAI/Anthropic/LangChain/etc. detected (auto-instrumented, zero config) **Recommendation matrix:** | Feature | Recommend when... | Reference | | ---------------- | -------------------------------------------------- | ---------------------------------------------- | | Error Monitoring | **Always** — non-negotiable baseline | `${SKILL_ROOT}/references/error-monitoring.md` | | Tracing | **Always** — NestJS lifecycle is auto-instrumented | `${SKILL_ROOT}/references/tracing.md` | | Profiling | Production + CPU-sensitive workloads | `${SKILL_ROOT}/references/profiling.md` | | Logging | Always; enhanced for structured log aggregation | `${SKILL_ROOT}/references/logging.md` | | Metrics | Custom business KPIs or SLO tracking | `${SKILL_ROOT}/references/metrics.md` | | Crons | `@nestjs/schedule`, Bull, or BullMQ detected | `${SKILL_ROOT}/references/crons.md` | | AI Monitoring | OpenAI/Anthropic/LangChain/etc. detected | `${SKILL_ROOT}/references/ai-monitoring.md` | Propose: _"I recommend Error Monitoring + Tracing + Logging. Want Profiling, Crons, or AI Monitoring too?"_ --- ## Phase 3: Guide ### Install ```bash # Core SDK (always required — includes @sentry/node) npm install @sentry/nestjs # With profiling support (optional) npm install @sentry/nestjs @sentry/profiling-node ``` > ⚠️ **Do NOT install `@sentry/node` alongside `@sentry/nestjs`** — `@sentry/nestjs` re-exports everything from `@sentry/node`. Installing both causes duplicate registration. ### Three-File Setup (Required) NestJS requires a specific three-file initialization pattern because the Sentry SDK must patch Node.js modules (via OpenTelemetry) **before** NestJS loads them. > **Before creating new files**, check Phase 1 results: > > - If `instrument.ts` already exists → modify it, don't create a new one. > - If a config class drives `Sentry.init()` → read options from the config instead of hardcoding env vars. > - If a Sentry DI wrapper exists → use it for runtime calls instead of importing `@sentry/nestjs` directly in services/controllers. #### Step 1: Create `src/instrument.ts` ```typescript import * as Sentry from "@sentry/nestjs"; // Optional: add profiling // import { nodeProfilingIntegration } from "@sentry/profiling-node"; Sentry.init({ dsn: process.env.SENTRY_DSN, environment: process.env.SENTRY_ENVIRONMENT ?? "production", release: process.env.SENTRY_RELEASE, // Data collection (SDK ≥ 10.57.0 — replaces deprecated sendDefaultPii) dataCollection: { // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit: // https://docs.sentry.io/platforms/javascript/guides/nestjs/configuration/options/#dataCollection // userInfo: false, // httpBodies: [], }, // Tracing — lower to 0.1–0.2 in high-traffic production tracesSampleRate: 1.0, // Profiling (requires @sentry/profiling-node) // integrations: [nodeProfilingIntegration()], // profileSessionSampleRate: 1.0, // profileLifecycle: "trace", // Structured logs (SDK ≥ 9.41.0) enableLogs: true, }); ``` **Config-driven `Sentry.init()`:** If Phase 1 found a typed config class (e.g. `SentryConfig`), read options from it instead of using raw `process.env`. This is common in NestJS apps that use `@nestjs/config` or custom config loaders: ```typescript import * as Sentry from "@sentry/nestjs"; import { loadConfiguration } from "./config"; const config = loadConfiguration(); Sentry.init({ dsn: config.sentry.dsn, environment: config.sentry.environment ?? "production", release: config.sentry.release, dataCollection: config.sentry.dataCollection ?? { // To disable sending user data and HTTP bodies, uncomment the lines below. For more info visit: // https://docs.sentry.io/platforms/javascript/guides/nestjs/configuration/options/#dataCollection // userInfo: false, // httpBodies: [], }, tracesSampleRate: config.sentry.tracesSampleRate ?? 1.0, profileSessionSampleRate: config.sentry.profilesSampleRate ?? 1.0, profileLifecycle: "trace", enableLogs: true, }); ``` When adding new SDK options (e.g. `dataCollection`, `profileSessionSampleRate`), add them to the config type so they can be configured per environment. #### Step 2: Import `instrument.ts` FIRST in `src/main.ts` ```typescript // instrument.ts MUST be the very first import — before NestJS or any other module import "./instrument"; import { NestFactory } from "@nestjs/core"; import { AppModule } from "./app.module"; async function bootstrap() { const app = await NestFactory.create(AppModule); // Enable graceful shutdown — flushes Sentry events on SIGTERM/SIGINT app.enableShutdownHooks(); await app.listen(3000); } bootstrap(); ``` > **Why first?** OpenTelemetry must monkey-patch `http`, `express`, database drivers, and other modules before they load. Any module that loads before `instrument.ts` will not be auto-instrumented. #### Step 3: Register `SentryModule` and `SentryGlobalFilter` in `src/app.module.ts` ```typescript import { Module } from "@nestjs/common"; import { APP_FILTER } from "@nestjs/core"; import { SentryModule, SentryGlobalFilter } from "@sentry/nestjs/setup"; import { AppController } from "./app.controller"; import { AppService } from "./app.service"; @Module({ imports: [ SentryModule.forRoot(), // Registers SentryTracingInterceptor globally ], controllers: [AppController], providers: [ AppService, { provide: APP_FILTER, useClass: SentryGlobalFilter, // Captures all unhandled exceptions }, ], }) export class AppModule {} ``` **What each piece does:** - `SentryModule.forRoot()` — registers `SentryTracingInterceptor` as a global `APP_INTERCEPTOR`, enabling HTTP transaction naming - `SentryGlobalFilter` — extends `BaseExceptionFilter`; captures exceptions across HTTP, GraphQL (rethrows `HttpException` without reporting), and RPC contexts > ⚠️ **Do NOT register `SentryModule.forRoot()` twice.** If Phase 1 found it already imported in a shared library module (e.g. a `SentryProxyModule` or `AnalyticsModule`), do not add it again in `AppModule`. Duplicate registration causes every span to be intercepted twice, bloating trace data. > ⚠️ **Two entrypoints, different imports:** > > - `@sentry/nestjs` → SDK init, capture APIs, decorators (`SentryTraced`, `SentryCron`, `SentryExceptionCaptured`) > - `@sentry/nestjs/setup` → NestJS DI constructs (`SentryModule`, `SentryGlobalFilter`) > > Never import `SentryModule` from `@sentry/nestjs` (main entrypoint) — it loads `@nestjs/common` before OpenTelemetry patches it, breaking auto-instrumentation. ### ESM Setup (Node ≥ 18.19.0) For ESM applications, use `--import` instead of a file import: ```javascript // instrument.mjs import * as Sentry from "@sentry/nestjs"; Sentry.init({ dsn: process.env.SENTRY_DSN, tracesSampleRate: 1.0, }); ``` ```json // package.json { "scripts": { "start": "node --import ./instrument.mjs -r ts-node/register src/main.ts" } } ``` Or via environment: ```bash NODE_OPTIONS="--import ./instrument.mjs" npm run start ``` ### Exception Filter Options Choose the approach that fits your existing architecture: #### Option A: No existing global filter — use `SentryGlobalFilter` (recommended) Already covered in Step 3 above. This is the simplest option. #### Option B: Existing custom global filter — add `@SentryExceptionCaptured()` decorator ```typescript import { Catch, ExceptionFilter, ArgumentsHost } from "@nestjs/common"; import { SentryExceptionCaptured } from "@sentry/nestjs"; @Catch() export class YourExistingFilter implements ExceptionFilter { @SentryExceptionCaptured() // Wraps catch() to auto-report exceptions catch(exception: unknown, host: ArgumentsHost): void { // Your existing error handling continues unchanged } } ```
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub