Integrate Sentry with Angular: Error Tracking and Source Maps

Introduction

Error tracking is an essential part of any production-ready application. It helps developers quickly identify issues, track performance, and maintain code quality. One of the most popular tools for error tracking and monitoring is Sentry.

In this post, I’ll walk you through the step-by-step integration of Sentry with Angular, including how to handle source maps properly to view unminified errors. I’ll also cover some challenges I faced, such as dealing with authentication tokens and automating the process with CI/CD pipelines using Docker and GitHub Actions.

KromaDev
Prerequisites

Before we start, here’s what you’ll need:

  • Angular 18+ installed and a working Angular project.
  • A Sentry account. You can sign up for free at Sentry.io.
  • Docker (if you’re using containerized builds).
  • GitHub Actions or another CI/CD tool for automation.
KromaDev
Step 1: Install the Sentry SDK in Angular

First, install the Sentry Angular SDK to capture errors, monitor interactions between multiple services or applications by enabling tracing and get to the root of an error or performance issue faster, by watching a video-like reproduction of a user session with session replay.

npm install @sentry/angular --save
KromaDev
Step 2: Configure Sentry in Your Angular Project
Register Sentry Providers in AppModule

To integrate Sentry with Angular’s error handling mechanisms, register the Sentry Providers in the root module (AppModule). This ensures that Sentry will automatically handle uncaught errors and routing performance.

Update your AppModule like this:

import { APP_INITIALIZER, ErrorHandler, NgModule } from "@angular/core";
import { Router } from "@angular/router";

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

@NgModule({
  // ...
  providers: [
    {
      provide: ErrorHandler,
      useValue: Sentry.createErrorHandler(),
    },
    {
      provide: Sentry.TraceService,
      deps: [Router],
    },
    {
      provide: APP_INITIALIZER,
      useFactory: () => () => {},
      deps: [Sentry.TraceService],
      multi: true,
    },
  ],
  // ...
})
export class AppModule {}
Update main.ts

In your Angular main.ts file, initialize Sentry. This setup ensures that Sentry is only active in production mode to avoid cluttering the dashboard with development errors.

/* main.ts */

import * as Sentry from '@sentry/angular';
import { BrowserTracing } from '@sentry/tracing';
import { AppModule } from './app/app.module';
import { enableProdMode } from '@angular/core';
import { environment } from './environments/environment';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

if (environment.production) {
  enableProdMode();

  Sentry.init({
    dsn: 'https://your-dsn.ingest.sentry.io/your-project-id',
    integrations: [Sentry.browserTracingIntegration(), Sentry.replayIntegration()],
    tracesSampleRate: 1.0,
    tracePropagationTargets: ['localhost', /^https:\/\/yourserver\.io\/api/],
    replaysSessionSampleRate: 0.1,
    replaysOnErrorSampleRate: 1.0,
  });
}

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch((err) => console.error(err));
Key Points:
  • Enable in Production Only: We check environment.production to enable production optimizations and to control when Sentry is active.
  • Sentry Integrations:
    • browserTracingIntegration() tracks app performance.
    • replayIntegration() records user sessions, helping visualize the steps leading up to errors.
  • Sampling Rates:
    • tracesSampleRate: Set to 1.0 to capture 100% of performance data (adjustable for production).
    • replaysSessionSampleRate: Captures 10% of all sessions.
    • replaysOnErrorSampleRate: Captures 100% of sessions with errors.

This setup ensures that Sentry is only initialized on production, providing error tracking and performance monitoring with minimal overhead.

KromaDev
Step 3: Configure Source Maps in Angular

To make the minified stack traces readable in Sentry, we need to upload source maps during the build process. Ensure that source maps are generated by modifying angular.json:

{
  "projects": {
    "your-project": {
      "architect": {
        "build": {
          "configurations": {
            "production": {
              "sourceMap": {
                "scripts": true,
                "styles": false,
                "hidden": true
              }
            }
          }
        }
      }
    }
  }
}
  • scripts: true enables source maps for JavaScript files.
  • hidden: true keeps source maps from being directly linked in the JavaScript files, but they are still accessible in the browser.
Since source maps can expose source code, it’s a good
practice to remove them from the server after they are
uploaded to Sentry.
KromaDev
Step 4: Upload Source Maps to Sentry

To ensure that Sentry can use your source maps for readable stack traces, you need to upload them to Sentry after each build. Sentry provides a wizard to simplify the process.

  • Run the Sentry Wizard
    • From your project’s root directory, run the following command to start the Sentry wizard, which will configure source map uploading for you:
npx @sentry/wizard@latest -i sourcemaps

This command will guide you through the setup process, automatically adding configuration and scripts to handle source map injection and uploading.

  • Inject Debug IDs and Upload Source Maps
    • After running the wizard, your package.json should include scripts for injecting Debug IDs into your source maps and uploading them to Sentry. These commands ensure that your source maps are prepared and sent to Sentry correctly.

The resulting commands might look something like this:

"build": "ng build && npm run sentry:sourcemaps",
"sentry:sourcemaps": "sentry-cli sourcemaps inject --org your-org --project your-project dist/your-project/browser && sentry-cli sourcemaps upload --org your-org --project your-project dist/your-project/browser"

sentry-cli sourcemaps inject: Injects Debug IDs into your JavaScript files. This allows Sentry to link errors to the correct source maps.

sentry-cli sourcemaps upload: Uploads the source maps to Sentry, making them available for error unminification.

  • Automate Source Map Uploading in Your CI/CD Pipeline
    • To ensure source maps are always uploaded to Sentry in production, you can add a step in your CI/CD pipeline to run these commands after each build.
  • Remove Source Maps After Uploading
    • To prevent source maps from being accessible in the production environment, you can delete them after uploading to Sentry. This can be handled in your Dockerfile or build script. 
  • Set the Sentry Auth Token in CI/CD and Dockerfile
    • To authenticate Sentry uploads, add the Sentry Auth Token as an environment variable and make sure it is accessible in the Dockerfile. For example, in a Dockerfile:
ARG SENTRY_AUTH_TOKEN
ENV SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN
...
RUN sentry-cli sourcemaps inject --org your-org --project your-project dist/your-project/browser && sentry-cli sourcemaps upload --org your-org --project your-project dist/your-project/browser
RUN rm -rf dist/your-project/browser/*.map
KromaDev
Step 5: Verify Your Sentry Setup

Once Sentry is configured in your Angular project, it’s important to verify that errors are being captured correctly. You can do this by manually triggering an error in your application.

Simulate an Error

Add the following code in your Angular component to simulate an error:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  ngOnInit() {
    throw new Error('Test error for Sentry!');
  }
}
Steps to Verify
  • Build and run your application
    • Start your Angular app using your production configuration
ng build
ng serve --configuration production
* It is critical to serve the exact same files from the build
that were used to upload the source maps to Sentry.
This ensures that Debug IDs in your minified files match the 
uploaded source maps, allowing Sentry to unminify errors
correctly.
  • Trigger the Error
    • Open the app in your browser. The simulated error will occur immediately when the component loads.
  • Check the Sentry Dashboard
    • Log in to your Sentry account.
    • Navigate to your project.
    • You should see the error, including stack traces and relevant details, in the Issues section.
sentry-error
  • What to Look For:
    • Error Stack Trace: Ensure the stack trace links to your original (unminified) source code. If it doesn’t, check your source map upload process.
    • Session Replay (Optional): If you’ve enabled session replay, verify that a recording of the user’s session leading up to the error is available.
KromaDev
Conclusion

Integrating Sentry with Angular helps developers quickly identify errors and monitor performance in production. Automating the process with Docker and CI/CD pipelines ensures that your team can focus on building features while maintaining code quality.

I hope this guide saves you time and helps you avoid some of the common pitfalls I faced. If you have any questions or suggestions, feel free to leave a comment below or reach out to me directly!

Leave a Reply

Your email address will not be published. Required fields are marked *