Track errors and Monitor your GraphQL backend with sentry SDK.

Hey guys 🤚, Glad to have you here! In this post we are going to cover something different. Once we have an app running, it's VERY IMPORTANT to see how our app behave for end users and ensure that everything works as expected. to do so, we need to monitor performances , track bugs and fix them as soon as they arrive. One of the most powerful SDK to do this is Sentry. In this tutorial, we will cover how to configure our GraphQL Backend with.

1. What is sentry ☝️ ?

Sentry.io is an external monitoring and logging platform as a service which can help you identify and triage errors API's and Services, webapps and mobile and desktop applications. This makes it an essential and versatile tool for any serious business or developer.

To have a quick overview of how sentry help you track errors, you can take a look at the sentry demo sandbox that show you something like this.

In this tutorial, we will setup sentry on a GraphQL API running on Apollo Server 3. Wether you are building a REST API or a GraphQL Backend, this tutorial will also working for you.

2. Setup 🛠

For this implementation, we will use a ready to use node.js graphql server we built on another post using Typescript. So we will fetch the source code that run a graphQL server with mocked data and JWT configured for authorization.

Since the directory containing the initial setup is part of a repository that host multiples tutorials source code each on a single folder, we will only clone the one with the initial setup we need to get start. Follow the folling steps from the terminal.

git clone --no-checkout https://github.com/Doha26/fullstack-hebdo-posts.git

cd fullstack-hebdo-posts

git sparse-checkout init --cone

git sparse-checkout set  05-nodejs-graphql-sentry

And now inside the folder, install node dependencies and start the server

 cd 05-nodejs-graphql-sentry && yarn && yarn start:dev

you will see the following output

This display the apollo server v3 landing page.

2. Let's setup a sentry project💻

First of all, go to sentry.io and register. After registration, you will see the following onboarding page.

Choose Install Sentry and click on the Start Button. The next page will ask you to choose the platform you are setting sentry for. In our case, we want to set this for a Node.JS GraphQL Backend. So we will choose Node.JS to create a Node.Js project on sentry platform.

The next step will display the following page that help you configure sentry for your Node.Js project.

In this screenshot, two elements are very important:

  • The DSN: This stand for Data Source Name. According to sentry documentation, A DSN tells a Sentry SDK where to send events so the events are associated with the correct project. The DSN configures the protocol, public key, server address, and project identifier. It is composed of the following parts:

{PROTOCOL}://{PUBLIC_KEY}:{SECRET_KEY}@{HOST}{PATH}/{PROJECT_ID}

Note:  The DSN should be treated as a secret and not shared with anyone. (We will place it inside a .env file)

  • The TracesSampleRate: determines the percent of events the monitor should send to the dashboard. A value of 1.0 sends 100% of the captured events – but if you find this to be too noisy you can reduce this number.

Next, you will see the sentry dashboard waiting for event and ready to catch errors.

3. Let's install  🪄

# Using yarn
yarn add @sentry/node @sentry/tracing @sentry/integrations

# Using npm
npm install --save @sentry/node @sentry/tracing @sentry/integrations

For this tutorial, we will create some environment variable inside a .env file containing JWT_USER_SECRET usefull for the previous blog post on how to Secure a GraphQL backend with JWT.  

JWT_USER_SECRET=ksjsjshbsid_fake_JWT_Token_Secret_Key_key_Here
APP_ENV=development
APP_NAME=Your_app_name_here
APP_REVISION=0.0.1
SENTRY_DSN=Your_DSN_here

Create a file under src/utils named sentry.ts or whatever you want that will host our sentry logic.

import * as Sentry from '@sentry/node'
import * as Tracing from '@sentry/tracing'
import * as core from 'express-serve-static-core'

import {
  RewriteFrames as RewriteFramesIntegration,
  ReportingObserver as ReportingObserverIntegration,
  ExtraErrorData as ExtraErrorDataIntegration,
  CaptureConsole as CaptureConsoleIntegration,
  Dedupe as DedupeIntegration
} from '@sentry/integrations'

const InitSentry = (app: core.Express): void => {
  Sentry.init({
    environment: process.env.APP_ENV,
    release: `${process.env.APP_NAME}-${process.env.APP_REVISION}` || '0.0.1',
    dsn: process.env.SENTRY_DSN,
    integrations: [
      new RewriteFramesIntegration({
        root: process.cwd()
      }) as RewriteFramesIntegration,
      new ExtraErrorDataIntegration({
        depth: 10
      }),
      new CaptureConsoleIntegration({
        // array of methods that should be captured
        // defaults to ['log', 'info', 'warn', StatusError, 'debug', 'assert']
        levels: ['error', 'warn', 'assert']
      }),
      new Sentry.Integrations.Http({ tracing: true }),
      new Tracing.Integrations.Express({ app }),
      new DedupeIntegration(),
      new ReportingObserverIntegration()
    ],
    tracesSampleRate: 1.0
  })
  app.use(Sentry.Handlers.requestHandler())
  app.use(Sentry.Handlers.tracingHandler())
  app.use(Sentry.Handlers.errorHandler())
}

export default InitSentry

And all we have to do is to call the InitSentry() function at server start. Inside src/index.ts file, add the following code :

// Bootstrap the server
const bootstrap = async () => {
  const db = await setupDb()
  const schema = await buildSchema({ resolvers: [EventResolver] })
  const app = express()

  // Init Sentry SDK here 
  InitSentry(app) // ADD THIS LINE <==

  // Express JWT Middleware that parse request and decode token
  app.use(
    expressJwt({

Everything is now ready. Let's let's raise an exception and see how sentry catches it. To raise an exception, let's  add a new Line and see how that will be captured by sentry.  

import * as Sentry from '@sentry/node' // Import this 

InitSentry(app) // Sentry init function 

Sentry.captureException(new Error('Testing Sentry SDK')) // Add this After

The Error is sent to sentry dashboard

Here is the error stacktrace.

Then, anywhere in your code base where you are logging errors (such as a try / catch block or a .catch() chain), add Sentry.captureException(error) (replacing error with the variable that represents your error object) to pass that error off to your Sentry monitor.

To query the  GraphQL server , it's required to send a JWT Token for queries. to get a JWT token, call the Login Mutation with email and password ( take a look at loadData() function inside src/index.ts to see how it works) and you will get a valid JWT Token that should be send in the header following the format Bearer xxx_token. Take a look at this Post to have more details.

You can navigate to the Performance tab to monitor and measure important metrics such as the FCP (First Contentful Paint), latency or downtime of any API requests, etc.

And that's is. Your server is now up and running with Sentry SDK well configured ✅

Thanks for reading, the source code is available here.

Follow me on socials media to stay up to date with latest posts.