Sentry not getting TypeScript source maps when integrated with NestJS
Asked Answered
N

2

7

I've created a small NestJS project recently which I attempting to integrate Sentry into. I have followed the instructions on the Nest-Raven package readme, along with the instructions provided by Sentry for TypeScript integration.

Unfortunately I cannot seem to get Sentry to display the TypeScript sourcemaps, only the regular JS ones, as you can see here:

Sentry Sourcemaps

I have Sentry initialised in main.ts as per the instructions

import { NestFactory } from '@nestjs/core';
import { RewriteFrames } from '@sentry/integrations';
import * as Sentry from '@sentry/node';
import { AppModule } from './app.module';

// This allows TypeScript to detect our global value
declare global {
  // eslint-disable-next-line @typescript-eslint/no-namespace
  namespace NodeJS {
    interface Global {
      __rootdir__: string;
    }
  }
}

global.__rootdir__ = __dirname || process.cwd();

async function bootstrap() {
  Sentry.init({
    dsn: 'https://mySentryDSN.ingest.sentry.io/0',
    integrations: [
      new RewriteFrames({
        root: global.__rootdir__,
      }),
    ],
  });
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();

I have also set up Nest-Raven to use a Global Interceptor

import { APP_INTERCEPTOR } from '@nestjs/core';
import { RavenInterceptor, RavenModule } from 'nest-raven';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [
    RavenModule,
    ...
  ],
  controllers: [AppController],
  providers: [
    AppService,
    {
      provide: APP_INTERCEPTOR,
      useValue: new RavenInterceptor(),
    },
  ],
})
export class AppModule {}

Has anyone else encountered this issue? I am thinking that perhaps I need to upload the sourcemaps directly to Sentry as per these intstructions, however as far as I know NestJS does not make use of Webpack so I am unsure how to proceed.

No answered 27/8, 2020 at 11:44 Comment(0)
N
5

So it turns out the issue was the directory I was providing to the RewriteFrames constructor. I had initially copied the global.__rootdir__ implementation from the Sentry Typescript documentation, but during debugging I found that __dirname and process.cwd() were returning different paths.

  dirname: '/Users/<name>/Documents/Projects/nest-test-project/dist',
  cwd: '/Users/<name>/Documents/Projects/nest-test-project'

Since __dirname was returning a truthy value, the path being given to Sentry was the one that included the dist folder. Once I changed the code to give Sentry the actual root path for the project, all of the Typescript sourcemaps were uploaded to Sentry.

EDIT: Some people were asking for an example of my tsconfig and the above code. I've since written my own SentryModule for bootstrapping Sentry, but the gist of the change is to find wherever you are calling new RewriteFrames({...}) and pass the correct root, which in my case was process.cwd().

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "ES2017",
    "lib": [ "ES2020.Promise" ],
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "sourceMap": true,
    "inlineSources": true,
    "sourceRoot": "/"
  }
}

main.ts or wherever Sentry is initialised

import { RewriteFrames } from "@sentry/integrations";

Sentry.init({
  dsn: "https://[email protected]/0",
  integrations: [
    new RewriteFrames({
      root: process.cwd(),
    }),
  ],
});
No answered 11/9, 2020 at 14:9 Comment(5)
hey, may you have a whole setup you used? I'm also stuck with nestjs and sentry, but it doesn't work with the correct path neither. Maybe you could post the config which was working for you? Thanks in advance! :)Dammar
I wish you could explain more, I also could not make that work. I came with the idea to set target to es2019 so the transpiled code is closer to the source code, then I can find the line easier. Any way, if you can please provide the tsconfig and setting you could make it work.Sagacity
I've edited my above answer to include an example of my tsconfig.json and how I passed process.cwd() to the Sentry constructor.No
Hello @ConorWatson and thank you for your example. I am struggling to get this to work for days ... No success yet, even having identical configuration as you and checking the value for process.cwd() - it's the correct project root. Is the uploading of typescript sourcemaps automated or should it be done by hand ? How can you check what's being sent ?Brassbound
@FlorinMateescu-mtscsoftware I think you will have to upload them. Check here for the options you have to provide sourcemaps to sentry: docs.sentry.io/platforms/javascript/sourcemaps 1. Uploaded directly to Sentry (strongly recommended) 2. Served publicly over HTTP alongside your deployed code. When you are using nest you definitely should not make your files publicly available (same goes for other node projects). I would suggest that you write a short script that publishes sourcemaps to sentry on every production ready build.Lincoln
C
0

You can make Nest use the webpack compiler with nest build --webpackas described here. It looks like Sentry also has documentation on how to get source map support using typescript without webpack so that may be worth checking out too.

Chroma answered 27/8, 2020 at 20:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.