How to use Sentry with Fastify

Updated by Tom Wells on

In this tutorial, we will cover how to use Sentry with the Fastify Node.js framework. This will cover not only collecting errors, but also environments and releases so you can get the most from your Sentry dashboard.

What are these?

Sentry is a popular, class-leading application monitoring and error tracking tool for backend API’s and services, webapps and mobile and desktop applications. This makes it an essential and versatile tool for any serious business or developer. Best of all, it has a generous free tier!

Fastify is a “fast and low-overhead” web framework for Node.js applications. It is genuinely fast and has support from a growing community of developers. It also comes with Typescript support out-of-the-box, has excellent documentation and built-in logging. In short, it should be a consideration to almost any Node.js developer in 2020 (and beyond).

Set up Sentry

First of all, it’s important to have a Sentry project:

  • Log into your Sentry account (if you don’t have one, create one).
  • Once your account and ‘team’ is created, create a new Node.js project. Name it whatever you like.
  • On the next page, you should get a ‘DSN’. This is used to connect your application to Sentry.

That’s it for now!

Set up your Fastify server

Ok, finally it’s time for some code. To start, you’ll need to install the dependencies in your Node.js project:

yarn add fastify @sentry/node dotenv

We’ll be using dotenv to store our Sentry DSN, it makes it a bit more secure when it comes to deploying your app.

So, create a .env file in the root of your project and add your Sentry DSN:

SENTRY_DSN=https://######@sentry.io/######

Now it’s time to spin up your Fastify server. Generally, I put all my application code within a src folder, but whether you do this is up to you. Either way, create a server.js file in your project with the following code:

/src/server.js
// 1) Dependencies
require('dotenv').config()
const fastify = require('fastify')()
const Sentry = require('@sentry/node')

// 2) Sentry
const pkg = require('../package.json')
Sentry.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.NODE_ENV,
  release: `<project-name>@${pkg.version}`
})

// 3) Fastify Sentry hook
fastify.addHook('onError', (request, reply, error, done) => {
  // Only send Sentry errors when not in development
  if (process.env.NODE_ENV !== 'development') {
    Sentry.captureException(error)
  }
  done()
})

// Fastify routes, other config
// More code etc

// 4) Set up server
const port = process.env.PORT || 4000
fastify.listen(port, (err, address) => {
  if (err) {
    console.error(err)
    process.exit(1)
  }
  console.log(`🚀 Listening on port ${port}`)
})

So what’s going on here?:

  • We’re importing our .env config with require('dotenv').config() and importing our dependencies.
  • We’re initialising Sentry including our release version (rename <project-name> to match your Sentry project name) and environment. This allows you to have multiple environments and track your errors through your entire pipeline.
  • We’re using a Fastify hook to send an event to Sentry using Sentry.captureException(error). We’re also preventing this from being sent when developing the app locally.
  • Finally, we start our Fastify server.

From this point on, you should receive errors into your Sentry dashboard! However, there is more you could achieve as this is a basic implementation. For example, we’ve not covered source maps here since there would be different ways to implement them depending on your bundler. But, feel free to play around.

Final words

There is a fastify-sentry npm package. However, this appears to be unmaintained and doesn’t support releases (which I consider to be an important feature within Sentry) so using this method appears to be a bit more flexible.

I hope you found this tutorial useful and if you want to keep up with what I'm doing, follow me on Twitter.