Skip to content

docs(js): Review and update Nest.js Quick Start guide #13497

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
May 20, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 115 additions & 1 deletion docs/platforms/javascript/common/install/commonjs.mdx
Copy link
Member

@Lms24 Lms24 Apr 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For NestJS-CommmonJS specifically, I don't think we should show ESM/CJS tabs here because later on we instruct users to import "./instrument". Since Nest ships with TS, we can simply let users create an instrument.ts file. (cc @chargome - let me know if I'm missing something or this sounds unreasonable to you)

image

I'm realizing that this is a common guide for various node platforms but it's quite confusing for NestJS I'd argue. So maybe it makes sense to create a Nest-specific version of it 🤔 In general, for the common guide, I don't think we should even show the ESM tab on the CommonJS installation page :)

also please see my other comment about nestjs-specific code in this page

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah sounds reasonable to just use a ts file here 👍

Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,118 @@ You need to create a file named `instrument.js` that imports and initializes Sen

You need to require or import the `instrument.js` file before requiring any other modules in your application. This is necessary to ensure that Sentry can automatically instrument all modules in your application:

<PlatformContent includePath="getting-started-use" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

h: the platform content here is important because this page is shown in various guides/frameworks. Right now, we'd show NestJS specific code in e.g. Node or Hono guides.

I think we can take two possibe routes:

  1. re-add the PlatformContent
  2. make a dedicated CommonJS page for NestJS (this would play well with the concern I addressed in the file comment above)

```javascript {filename: main.ts}
// Import this first!
import "./instrument";

// Now import other modules
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";

async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}

bootstrap();
```

Afterwards, add the `SentryModule` as a root module to your main module:

```javascript {filename: app.module.ts} {2, 8}
import { Module } from "@nestjs/common";
import { SentryModule } from "@sentry/nestjs/setup";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";

@Module({
imports: [
SentryModule.forRoot(),
// ...other modules
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
```

If you're using a global catch-all exception filter (which is either a filter registered with `app.useGlobalFilters()` or a filter registered in your app module providers annotated with a `@Catch()` decorator without arguments), add a `@SentryExceptionCaptured()` decorator to the filter's `catch()` method.
This decorator will report all unexpected errors that are received by your global error filter to Sentry:

```javascript {2, 6}
import { Catch, ExceptionFilter } from '@nestjs/common';
import { SentryExceptionCaptured } from '@sentry/nestjs';

@Catch()
export class YourCatchAllExceptionFilter implements ExceptionFilter {
@SentryExceptionCaptured()
catch(exception, host): void {
// your implementation here
}
}
```

By default, only unhandled exceptions that are not caught by an error filter are reported to Sentry.
`HttpException`s (including [derivatives](https://docs.nestjs.com/exception-filters#built-in-http-exceptions)) are also not captured by default because they mostly act as control flow vehicles.

If you don't have a global catch-all exception filter, add the `SentryGlobalFilter` to the providers of your main module.
This filter will report any unhandled errors that aren't caught by other error filters to Sentry.
**Important:** The `SentryGlobalFilter` needs to be registered before any other exception filters.

```javascript {3, 9}
import { Module } from "@nestjs/common";
import { APP_FILTER } from "@nestjs/core";
import { SentryGlobalFilter } from "@sentry/nestjs/setup";

@Module({
providers: [
{
provide: APP_FILTER,
useClass: SentryGlobalFilter,
},
// ..other providers
],
})
export class AppModule {}
```

<Expandable title="Using Microservices?">

If you are using `@nestjs/microservices` make sure to handle errors in RPC contexts correctly by providing your own `RpcExceptionFilter` (see https://docs.nestjs.com/microservices/exception-filters).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC we generally prefer "you're" over "you are" (but again, feel free to disregard, no strong opinions)

Suggested change
If you are using `@nestjs/microservices` make sure to handle errors in RPC contexts correctly by providing your own `RpcExceptionFilter` (see https://docs.nestjs.com/microservices/exception-filters).
If you're using `@nestjs/microservices` make sure to handle errors in RPC contexts correctly by providing your own `RpcExceptionFilter` (see https://docs.nestjs.com/microservices/exception-filters).

`SentryGlobalFilter` in a [hybrid application](https://docs.nestjs.com/faq/hybrid-application) does not extend `BaseRpcExceptionFilter` since this depends on `@nestjs/microservices`.

Use `Sentry.captureException(exception)` in your custom filter in case you want to send these errors to Sentry:

```typescript
import { Catch, RpcExceptionFilter, ArgumentsHost } from "@nestjs/common";
import { Observable, throwError } from "rxjs";
import { RpcException } from "@nestjs/microservices";
import * as Sentry from "@sentry/nestjs";

@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
Sentry.captureException(exception); // optional
return throwError(() => exception.getError());
}
}
```

</Expandable>

If you have error filters for specific types of exceptions (for example `@Catch(HttpException)`, or any other `@Catch(...)` with arguments) and you want to capture errors caught by these filters, capture the errors in the `catch()` handler with `Sentry.captureException()`:

```javascript {9}
import { ArgumentsHost, BadRequestException, Catch } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
import { ExampleException } from './example.exception';
import * as Sentry from '@sentry/nestjs';

@Catch(ExampleException)
export class ExampleExceptionFilter extends BaseExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
Sentry.captureException(exception);
return super.catch(new BadRequestException(exception.message), host)
}
}
```
4 changes: 1 addition & 3 deletions docs/platforms/javascript/guides/nestjs/index.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Nest.js
description: "Learn about using Sentry with Nest.js."
description: "Learn how to set up Sentry in your Nest.js app and capture your first errors."
sdk: sentry.javascript.nestjs
fallbackGuide: javascript.node
categories:
Expand All @@ -9,6 +9,4 @@ categories:
- server-node
---

This guide explains how to set up Sentry in your Nest.js application.

<PlatformContent includePath="getting-started-node" />
27 changes: 19 additions & 8 deletions platform-includes/getting-started-config/javascript.nestjs.mdx
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
```javascript {tabTitle:ESM} {filename: instrument.mjs}
import * as Sentry from "@sentry/nestjs";
// ___PRODUCT_OPTION_START___ profiling
import { nodeProfilingIntegration } from '@sentry/profiling-node';
import { nodeProfilingIntegration } from "@sentry/profiling-node";
// ___PRODUCT_OPTION_END___ profiling

// Ensure to call this before importing any other modules!
Sentry.init({
dsn: "___PUBLIC_DSN___",

// Adds request headers and IP for users, for more info visit:
// https://docs.sentry.io/platforms/javascript/guides/nestjs/configuration/options/#sendDefaultPii
sendDefaultPii: true,

// ___PRODUCT_OPTION_START___ profiling
integrations: [
// Add our Profiling integration
Expand All @@ -20,14 +20,20 @@ Sentry.init({
// ___PRODUCT_OPTION_END___ profiling
// ___PRODUCT_OPTION_START___ performance

// Add Tracing by setting tracesSampleRate
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for tracing.
// We recommend adjusting this value in production
// Learn more at
// https://docs.sentry.io/platforms/javascript/guides/nestjs/configuration/options/#tracesSampleRate
tracesSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ performance
// ___PRODUCT_OPTION_START___ profiling

// Set sampling rate for profiling
// Set profilesSampleRate to 1.0 to profile 100%
// of sampled transactions.
// This is relative to tracesSampleRate
// Learn more at
// https://docs.sentry.io/platforms/javascript/guides/nestjs/configuration/options/#profilesSampleRate
profilesSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ profiling
});
Expand All @@ -50,16 +56,21 @@ Sentry.init({
// ___PRODUCT_OPTION_END___ profiling
// ___PRODUCT_OPTION_START___ performance

// Add Tracing by setting tracesSampleRate
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for tracing.
// We recommend adjusting this value in production
// Learn more at
// https://docs.sentry.io/platforms/javascript/guides/nestjs/configuration/options/#tracesSampleRate
tracesSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ performance
// ___PRODUCT_OPTION_START___ profiling

// Set sampling rate for profiling
// Set profilesSampleRate to 1.0 to profile 100%
// of sampled transactions.
// This is relative to tracesSampleRate
// Learn more at
// https://docs.sentry.io/platforms/javascript/guides/nestjs/configuration/options/#profilesSampleRate
profilesSampleRate: 1.0,
// ___PRODUCT_OPTION_END___ profiling
});
```

1 change: 1 addition & 0 deletions platform-includes/getting-started-node/javascript.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Our next recommended steps for you are:
<Expandable permalink={false} title="Are you having problems setting up the SDK?">

- Check out alternative <PlatformLink to="/install">installation methods</PlatformLink>
- Find various topics in <PlatformLink to="/troubleshooting">Troubleshooting</PlatformLink>
- [Get support](https://sentry.zendesk.com/hc/en-us/)

</Expandable>
70 changes: 9 additions & 61 deletions platform-includes/getting-started-use/javascript.nestjs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ async function bootstrap() {
bootstrap();
```

Afterwards, add the `SentryModule` as a root module to your main module:
Afterward, add the `SentryModule` as a root module to your main module:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Afterward, add the `SentryModule` as a root module to your main module:
Afterwards, add the `SentryModule` as a root module to your main module:

I think? 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both forms are correct, although the variant with “s” is used in British English and the one without in American English 👍


```javascript {filename: app.module.ts} {2, 8}
import { Module } from "@nestjs/common";
Expand All @@ -33,28 +33,15 @@ import { AppService } from "./app.service";
export class AppModule {}
```

If you're using a global catch-all exception filter (which is either a filter registered with `app.useGlobalFilters()` or a filter registered in your app module providers annotated with a `@Catch()` decorator without arguments), add a `@SentryExceptionCaptured()` decorator to the filter's `catch()` method.
This decorator will report all unexpected errors that are received by your global error filter to Sentry:
By default, only unhandled exceptions that are not caught by an error filter are reported to Sentry. Additionally, `HttpException`s (including [derivatives](https://docs.nestjs.com/exception-filters#built-in-http-exceptions)) are not captured automatically as they mostly act as control flow vehicles.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we start with the Error Capturing topic.
I was wondering if it would make sense to not have this in "Apply Instrumentation to Your App" and instead put it in a dedicated section, "Step x: Capture Nest.js Errors" -> similar to how we have it for React .

But then this only seems to be documented for CJS - I was wondering why we don't have this documented for ESM? Or is this not needed/possible?

I don't see this as part of this PR -- we can address in a future issue/PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering if it would make sense to not have this in "Apply Instrumentation to Your App" and instead put it in a dedicated section, "Step x: Capture Nest.js Errors"

This sounds reasonable to me!

But then this only seems to be documented for CJS - I was wondering why we don't have this documented for ESM? Or is this not needed/possible?

I think this should be the same for CJS and ESM. Or IOW, the filters require should be applied in the same way regardless of ESM/CJS

I don't see this as part of this PR -- we can address in a future issue/PR.

that also sounds reasonable :D


```javascript {2, 6}
import { Catch, ExceptionFilter } from '@nestjs/common';
import { SentryExceptionCaptured } from '@sentry/nestjs';
##### Basic Error Capture

@Catch()
export class YourCatchAllExceptionFilter implements ExceptionFilter {
@SentryExceptionCaptured()
catch(exception, host): void {
// your implementation here
}
}
```
Add the `SentryGlobalFilter` to the providers of your main module. This filter will report any unhandled errors that aren't caught by other error filters to Sentry.

By default, only unhandled exceptions that are not caught by an error filter are reported to Sentry.
`HttpException`s (including [derivatives](https://docs.nestjs.com/exception-filters#built-in-http-exceptions)) are also not captured by default because they mostly act as control flow vehicles.

If you don't have a global catch-all exception filter, add the `SentryGlobalFilter` to the providers of your main module.
This filter will report any unhandled errors that aren't caught by other error filters to Sentry.
**Important:** The `SentryGlobalFilter` needs to be registered before any other exception filters.
<Alert level="warning" title="Important">
Make sure to register `SentryGlobalFilter` before any other exception filters.
</Alert>

```javascript {3, 9}
import { Module } from "@nestjs/common";
Expand All @@ -73,45 +60,6 @@ import { SentryGlobalFilter } from "@sentry/nestjs/setup";
export class AppModule {}
```

<Expandable title="Using Microservices?">

If you are using `@nestjs/microservices` make sure to handle errors in RPC contexts correctly by providing your own `RpcExceptionFilter` (see https://docs.nestjs.com/microservices/exception-filters).
`SentryGlobalFilter` in a [hybrid application](https://docs.nestjs.com/faq/hybrid-application) does not extend `BaseRpcExceptionFilter` since this depends on `@nestjs/microservices`.

Use `Sentry.captureException(exception)` in your custom filter in case you want to send these errors to Sentry:

```typescript
import { Catch, RpcExceptionFilter, ArgumentsHost } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { RpcException } from '@nestjs/microservices';
import * as Sentry from '@sentry/nestjs';

@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
Sentry.captureException(exception); // optional
return throwError(() => exception.getError());
}
}
```


</Expandable>

##### Fine-Tuning Error Capture

If you have error filters for specific types of exceptions (for example `@Catch(HttpException)`, or any other `@Catch(...)` with arguments) and you want to capture errors caught by these filters, capture the errors in the `catch()` handler with `Sentry.captureException()`:

```javascript {9}
import { ArgumentsHost, BadRequestException, Catch } from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';
import { ExampleException } from './example.exception';
import * as Sentry from '@sentry/nestjs';

@Catch(ExampleException)
export class ExampleExceptionFilter extends BaseExceptionFilter {
catch(exception: unknown, host: ArgumentsHost) {
Sentry.captureException(exception);
return super.catch(new BadRequestException(exception.message), host)
}
}
```
For more precise control over error reporting in global catch-all exception filters, specific exception filters, or microservices, check out our [CommonJS installation documentation](/platforms/javascript/guides/nestjs/install/commonjs/).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m: I don't think we should link to the CJS guide for this. Either we find a place for it here, or we do something like we have in Angular or React where we explain the intricacies of the filters in a "NestJS Features -> Exception Filters" page. wdyt?

42 changes: 40 additions & 2 deletions platform-includes/getting-started-verify/javascript.nestjs.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,44 @@
### Issues

First, let's verify that Sentry captures errors and creates issues in your Sentry project. Add the following route to your application, which will call an undefined function, triggering an error that Sentry will capture:

```javascript
@Get("/debug-sentry")
getError() {
throw new Error("My first Sentry error!");
getError() {
setTimeout(() => {
try {
foo();
} catch (e) {
Sentry.captureException(e);
}
}, 99);
}
```

<OnboardingOption optionId="performance">
### Tracing

To test your tracing configuration, update the previous code snippet by starting a performance trace to measure the time it takes for the execution of your code:

```javascript
@Get("/debug-sentry")
getError() {
Sentry.startSpan(
{
op: "test",
name: "My First Test Transaction",
},
() => {
setTimeout(() => {
try {
foo();
} catch (e) {
Sentry.captureException(e);
}
}, 99);
},
);
}
```

</OnboardingOption>