Angular with Sentry — A Step-by-Step Guide

Amit Chaudhary
11 min readApr 27, 2020

--

Catching bugs and fixing them before they get you in trouble is the most important thing that you can do as a developer. But to fix bugs, you need to CATCH them :) And how do you do so? Of course, through logs.

Motivated by the same thought, I started searching on the web to find the way for handling errors in my Angular application and I found that there are a plethora of options available on the market to make a developer’s life easy. Gone are the days when you had to manage everything on your own. We can easily integrate third-party tools and get started with solving bugs rather than running amock.

Why Third-Party Tools?

The answer to this question is simple: why to reinvent a wheel?

Yes, why waste time finding your custom solutions for logging when there are tools available at your disposal which are far better than yours as they have been used by millions of people and are well-tested and get constant updates.

Sentry, one such tool, is open-source (doesn’t mean the whole product is free of cost) and highly recommended by people who have reaped its benefits. Though there are other logging tools available like Rollbar, TrackJS, etc. But I believe Sentry stands out in the crowd due to wide-array of integrations with other popular tools (Jira, BitBucket, etc) and allowing a developer to play with it before finalizing it. Still, before jumping to the conclusion, you must do some analysis of all the options available on the table and see which fits best according to your needs.

In this article, we will see how to integrate Sentry in our Angular application to track errors. Let’s start then.

Step 1: Create a New Angular Project

We will create a small project for demo and produce an error intentionally and check how it is handled by Sentry.

As of writing this article, the latest version of Angular is 9, so we will be creating our sample application in the same version. However, you can have Sentry configured for all previous versions too, with little changes.

Create a project using the below command

ng new sample-project

Change the directory and run the application

cd sample-project

ng serve -o

Check the application in the browser

If all has gone well then you must be seeing a similar page in your browser.

We will delete all the content from app.component.html file and have just one simple button calling a function.

And we will write the same function in app.component.ts file.

Now, run the application and hit the button. You will see below error logged in the console:

As it is running in the development environment, you can also see the source file app.component.ts , where the issue occurred, associated with this error.

Well, this is good as you can easily debug the application and fix the error. But the story is not the same for production builds. Is it?

Create a production build

ng build — -prod

You can see that below files were generated by Angular:

If you face memory issues while creating a production build, then execute below command which will allocate more memory at the time of build.

node — max_old_space_size=5048 ./node_modules/@angular/cli/bin/ng build — prod — base-href=/ — aot — output-hashing=none

Run the production build

You can skip this part if you already have the IIS server or HTTP server installed on your machine and you can deploy the application on it directly. But if you don’t have it, then please install lite angular-http-server where we can deploy our production build.

npm install angular-http-server -g

Just change the directory to dist folder and execute below command:

angular-http-server -p 9000

Note: By default, it runs on 8080 port.

Now, open the application on localhost:9000 and hit the ‘Call Sample Function’ button and you will see below error:

Now, let’s see how to capture the same error in Sentry in the following steps.

Step 2: Integrate Sentry

Create Account

You can create a free developer account and log 5,000 events (errors) per month and access core features. If you need more developer accounts then you need to pay for it. But I think, 5000 events are more than enough for testing the platform and even you can use it in production if your application is small enough.

Follow the wizard shown in Sentry.

Select Angular as the platform and hit the ‘Create Project’ button.

Install the Sentry SDK and capture the first event.

Download Sentry Browser library through NPM

npm install @sentry/browser

Add Sentry configuration in the app.component.ts

You can also set custom data along with id, username, and email. This data will be associated with every bug produced while using the application so that it is easier to find out the specific error in Sentry. Over here they are just static values, but in your application, you can get the details of the logged-in user.

By default, Angular logs all the errors through its Error Handler class. But if we want to handle the errors by ourselves, for example, in our case we want to use Sentry to log all errors, then we need to override it in app.module.ts file. As you can see in the below image, we will use Sentry only in the production environment and not in the development.

Switching error handlers dynamically.
Overriding error handler.

Now run the application and hit the ‘Call Sample Function’ button. The error which the user sees in the browser can also be seen in Sentry. As soon as the event (error) is submitted to Sentry, it will show you the message shown in the below image confirming that the integration was successful.

Click ‘Take me to my event’ button and see the event and its full stacktrace.

We have achieved what we had set out for. But wait! What about the source code? We can’t see at which line the error occurred in our source code. The solution is source map.

Step 3: Source Map

You might not be aware but you are already using source map when you debug your application in development server.

Source map is nothing but a JSON file that contains all the necessary information to convert the transpiled (minified) code back to the original sources. In short:

.js + .js.map = source code

When you create a production build, source maps are not generated for you. This means, you WILL NOT see original files associated with the error in the browser because of the absence of source maps. This is because you are running the application in the production environment and not in the development.

Even if you try to find the original source code in the browser, you won’t get it.

Before we deep dive into how to see the source code in production builds we need to understand its existence and importance.

As you know, it’s good to see our source code while developing the application so that if there is any bug we can quickly fix it. But would you like to reveal your code to the public when your application goes live? It depends. If it is an open-source project then there is no harm in it. But if it is otherwise, then a big NO. A security breach. Hackers are around all the time.

This is why Angular, by default, doesn’t generate source code for production builds. BUT, in case you really need it (as we will require it in Sentry) then it does provide the option to do so. You can open angular.json file and update the value of sourceMap property to true. This will tell Webpack compiler to generate source map files along with minified files.

Now run the production build command again and see that that there are some extra files with .js.map extension.

As you can see, we can now search source files in the browser as well. This is because, we have source maps available now.

But how come the browsers know our source code based on source map files? Actually, when you open Dev Tools, the browser looks for the last line in each minified file.

So should we have source maps or not?

We are back to square one. We need source map files for Sentry, but we also want to hide them from the public. This was a big concern for a long time, so since Angular 7.2, we do get more granular control over generating source map files.

The hidden property tells the Webpack compiler to generate the source map files but DO NOT inject the last commented line in minified file. This will prevent browsers from fetching the source map file which will ultimately stop showing source code in production builds.

However, this won’t mean that source maps are not there. They are, and will also get loaded into the browser which will increase the loading time of the application. So, we need to delete them all. But if we delete these files, then how will we upload them on Sentry?

Simple, first upload and then delete the files! Ha ha ha ……

Now let’s see how to upload source maps on Sentry.

Install Sentry CLI

To upload the source map files, we need sentry-cli plugin. So, we will install it using below command.

npm install @sentry/cli -g

After installing it, if you find any issue executing it, then please make sure that your environment variable is set properly.

Login to Sentry

Execute below command and it will ask for the authentication token.

sentry-cli login

Generate Token

You can get the token from Sentry.

Click ‘Create New Token’ and do not change any scope. Keep it as it is. Copy the token and paste in CMD. Sentry will store the token in .sentryclirc file so that you don’t need to pass token every time.

Upload Source Maps

To upload the source maps, Sentry requires release version. It’s mandatory. The release version configured in app.component.ts and here must be same. In our demo, we have set our release as v1.0.1. Sentry uses these release versions to store bugs accordingly. For example, it might be possible that QA environment is running v1.0.1 release but in production there is v1.0.2.

Every time a new release is published, we need to upload source maps of that specific release.

You don’t need to create the same release versions for different environments. The release versions are shared across the environments. So, if you have same release running in all the environments, then you need to upload source maps just ONCE. Let’s now create our first release using below command.

sentry-cli releases new “v1.0.1”

Now try to upload source maps

sentry-cli releases files “v1.0.1” upload-sourcemaps dist\sample-project\

By executing above command you might get an error asking for organization and project slugs (unique names). You can get that information from Sentry as shown in below images:

Organization slug:

Project slug:

Add organization and project slugs in sentryclirc file as defaults. If you have only one organization and project then you don’t need to pass these slugs every time as Sentry CLI will take these values from sentryclirc.

Once the values are set then you will be able to upload the source maps without any issues.

Verify the source maps are uploaded on Sentry under the v1.0.1 release. Now you can delete the source maps from your dist folder as we don’t need them now. For Windows, just type del *.map and all files will get deleted.

Once you have the source maps uploaded, run the production build and hit the button ‘Call Sample Function’ button and generate the error. Now, you will be able the same error with original source code. Sentry will automatically highlight the line where the error occurred.

Tips/FAQs

How to delete all the artifacts from Sentry?

Just execute sentry-cli releases “v1.0.1” delete -all

Does Sentry have effect on application performance?

Honestly, I have not seen even the slightest issue in the performance of the application.

What if Sentry doesn’t show source code in the event?

Well, you are not alone. Lots of people have faced this issue, including me. Follow the below link and you might get the answer.

I am running Angular 7.1 version and I don’t want to upgrade to version 8, then how can I use the hidden property in angular.json file?

You just need to upgrade it to 7.2/7.3. Below link will show you how to do it.

What if don’t need to use sentryclirc file?

You can set environment variables.

If you enjoyed reading the article, don’t forget to clap! :)

--

--

Amit Chaudhary

A software developer by profession but a teacher from the heart.