Automatically Find and Log Bugs in Your Node.js App with Raygun

Free Course

Build Your First Node.js Website

Node is a powerful tool to get JavaScript on the server. Use Node to build a great website.

Writing good code is hard. Diagnosing code related issues is even harder. Sometimes the issue is obvious but other times it can drive you insane trying to figure out why the code isn’t functioning properly. That’s when we dive into server logs, commit history and jump on 2am Skype calls to try and recreate the issue and fix it.

Raygun is a company and app that aims to simplify the diagnostics of errors and crashes in your applications.

Raygun detects and diagnoses errors and crashes in your application and makes them available on your Raygun dashboard. Included in these reports are full diagnostics information and stack traces to help you pinpoint the root cause of issues and fix them.

Raygun_Logo_600px_Flat_Blue

In this tutorial, we’ll walk through the process of setting up Raygun with a simple application. Raygun supports all major web and mobile languages and platforms ranging from Android to Unity 3D and can be plugged in easily into any of their many supported languages like PHP, Node, Angular, Ruby, and more.

Our Application

For our tutorial we will build a small, buggy and simple Node.js application that will showcase how you can integrate Raygun into your application. Here we will be focusing on triggering errors and handling them with Raygun so we will not be developing a UI for our app.

To get started we will first create an account on Raygun. Raygun has a free 30 day trial that anyone can sign up for and evaluate the software and then plans start at $49/month.

Getting Started with Raygun

The onboarding process for setting up Raygun is very simple.

  1. Create your account
  2. Choose a name for your first application
  3. Select the platform/language
  4. Integrate

1. Start Your Raygun App

signup-1

The key takeaway on the first step is to configure how often you would like to be alerted when Raygun receives errors. You can select to receive an update each time an error comes in, but that may be overkill, so going for something like a daily summary may be more suitable.

For our tutorial we will enable all settings so that we are alerted any time an error is thrown in our application.

2. Select the Language

signup-2

Step 2 is very straightforward, simply select the language your application is written in. The language you select will determine the instructions you receive on step 3.

3. Setup Instructions

signup-3

Once you get the final step you will be given instructions on how to integrate Raygun into your application. Since we’re working with Node for this tutorial, we will be following the directions to setup Raygun with Node – and specifically the Express framework. S

Raygun and Node/Express

Setting up Raygun with express requires only three steps.

  • Install the Raygun dependency by running npm install raygun
  • Include the Raygun module in your application – in our example all of the code is stored in a single server.js so we can include the Raygun module by just including var raygun = require("raygun");
  • Finally we create an instance and initiate Raygun as well as store it in a variable so that we can use it throughout the application.

Let’s take a look at our code so far:


// grab the modules we need
var express = require("express"); 
var raygun = require("raygun");

// initiate a raygun client
var raygunClient = new raygun.Client().init({apiKey: "API-KEY-HERE"});

// get an instance of express for our application
var app = express();

// we will define routes here

// IMPORTANT: per Express and Raygun documentation, for Raygun to properly capture application based errors it's middleware will need to be called before the app.listen function
app.use(raygunClient.expressHandler); 

// start our app on port 8080
app.listen("8080");

If you’ve used Node.js in the past, you should feel right at home. If you are new to NodeJs, what we did here was include the express and Raygun modules in our application on lines 1 and 2, then initiate a Raygun client on line 4 with the minimum required settings as well as initiated the express application on line 8.

On line 9 we are declaring a middleware that will be used with our app called raygunClient.expressHandler.

Finally, we made our express app listen on port 8080. Since we haven’t setup any routes we won’t see anything if we navigate to localhost:8080 just yet.

Logging a Simple Error to Raygun

Now that we have our simple skeleton application built we are ready to start capturing errors with Raygun. The following code samples will be inserted between the var app = express() and app.use(raygunClient.expressHandler) statements.

We will setup a couple of routes that will be configured to throw different types of errors and then we will investigate these errors in detail in the Raygun dashboard.

Let’s start by throwing the simplest error possible. When the user navigates to the /simple-error route, this error will be logged.

We will not actually throw the error to stop the application flow, but will instead display a message of what type of error was thrown.


// create the simple-error route
app.get('/simple-error', function(req, res){
    // create a new error object
    var err = new Error('Simple Error');

    // send that error off to raygun
    raygunClient.send(err);

    // send a message back to the browser
    res.send('Simple Error Thrown');
});

With this code in place, let’s run our app and navigate to the /simple-error route. Once you see the message “Simple Error Thrown” in your browser. You can also navigate to your Raygun dashboard to confirm that error we just created has successfully fired.

If you had set your email settings to receive alerts any time an error is triggered you should have also received an email telling you that your application has triggered an error.

The email you receive will also have links to take quick actions such as mark the error resolved, ignore the error or view additional details on your Raygun dashboard.

Before we create additional errors and go deeper into the code – I want to familiarize you with the Raygun dashboard. The next section will give you an overview of the major sections of the Raygun dashboard webapp and then we’ll get back to triggering and handling errors.

Understanding the Raygun Dashboard

Now that we have our simple application set up and sending errors, let’s take a closer look at the Raygun Dashboard and understand how to best utilize it.

Dashboard View

railgun-dashboard

The dashboard view gives us an overall summary of what is going on in our application. The two key elements displayed here are a graph displaying the number of errors and when they occurred and a summary of errors below it. We can click into each individual error to find see additional details.

Errors in Raygun are are grouped into four categories: active, resolved, ignored and permanently ignored.

  • Active – errors that have been reported into Raygun but have not had an action taken yet. These errors are pending interaction and further classification
  • Resolved – if an error is marked resolved it will go into this category. If the error is raised again it will move from resolved to active. Additionally, there is a Resolved in Version category that will suppress an error for that version of the software
  • Ignored – errors placed in this category are non-critical – thus being ignored. You may still want to know that these errors are occurring so you will be notified but these types of errors should not cause major issues with your application
  • Permanently Ignored – you will not be directly notified of errors that fall in this category and they will not be placed in the “active” category if they reoccur.

Users View

railgun-user

If you are using the user’s functionality provided by Raygun – you will be able to see a list of users and what issues they are experiencing in this panel. You can also be able to contact these users via email or social media.

Deployments View

railgun-deployment

If you have Raygun implemented for deployment tracking you will be able to see outcomes of deployments in this view. We will not be covering Raygun deployment tracking functionality in this tutorial.

Application Settings View

railgun-app-settings

In the application settings you can view your API Key, change app name, configure different integrations as well as delete your application if you are no longer using it.

Other Views

railgun-team

The remaining tabs allow you to provide feedback for the Raygun team and also manage your team. Raygun gives you the ability to manage individual users as well as create teams to best coordinate the bug squashing efforts for your organization.

Examining Errors in the Raygun Dashboard

railgun-error

Earlier in this tutorial we created and triggered a simple error via Raygun. Let’s go into the Raygun dashboard and see what type of information Raygun has gathered for us. Clicking on the error takes us to a detailed view of the error.

Here we can see a summary of the error that includes vital statistics such as

  • When the error occurred
  • Number of occurrences
  • The message we defined (in our case ‘Simple Error’)
  • The stacktrace of the error

User Machine Information

If we navigate to the Environment tab we can see a detailed breakdown of the machine that triggered the error including:

  • Operating system
  • RAM
  • Processor architecture
  • Processor core count

This environment information can be very useful for Android, iOS, and Unity3D based applications and also has it’s uses for web applications as well.

In the detailed bug view, you can see and leave comments for other members of your team to help the diagnosing and resolution of the error. Additionally, you can assign the Raygun state of the error and decide next steps to take in resolving and handling the error.

Automatically Logged Errors

In our earlier example, we manually created and triggered an error by using the raygunClient.send() function. Raygun will also capture and handle any application generated errors as well.

To showcase this functionality, we’ll create a new route and call it ‘/app-error’. We will be triggering a JavaScript ReferenceError by trying to call an undefined variable. See the code sample below.


// create the route to show a logged app error
app.get('/app-error', function(req, res){
    // sunday is an undeclared variable
    var message = "Hello world! Today is " + sunday; 

    // send this message back to the client
    res.send(message);
});

Running the application and navigating to the http://localhost:8080/app-error route will not produce the message “Hello World! Today is Sunday”, but will instead give us ReferenceError telling us that sunday is not defined as well as the stacktrace for this error.

If we dig deeper into this error on the Raygun dashboard we will be able to see the HTTP request information for this error including the HTTP method, hostname, header values and more.

Raygun will automatically capture these application level errors and send you appropriate alerts which makes it very plug and play for our applications.

User Tracking

This is one of the really neat features of Raygun. Raygun has the ability to track users that experience errors with your application. Additionally, Raygun gives you the ability to contact affected users via email or social media and let them know when an issue has been fixed or provide other types of updates.

This really helps automate our bug fix flow since we’ll know the direct user that was affected and be able to follow up with them on their specific issue. No more asking for screenshots and logs when a user chimes in with a problem.

In our code example, we will be creating a static user to showcase this functionality, but in a real application you would get the actual logged in user information.

We will create a route /user-error that will generate a generic JavaScript Error as we did in our initial example, but here we will include the user’s information using the raygunClient.user method. Take a look at the code sample below to see how we accomplish this.


// attach a user to a raygun error
app.get('/user-error', function(req, res){

    // create a raygun user
    raygunClient.user = function(req) {
        var user = {
            identifier: "<a href='mailto:ado@scotch.io'>ado@scotch.io</a>",
            fullName : "Ado Kukic",
            isAnonymous : false
        } 
        return user;
    }

    // create the error
    var err = new Error("User Tracking Error");

    // send the error
    raygunClient.send(err);

    // send info back to the browser
    res.send("User Tracking Error");

});

Running this code and navigating to the http://localhost:8080 will display the “User Tracking Error” message in your browser.

If you navigate to your Raygun dashboard though, and click into the Users tab, you will be able to see that our user “Ado Kukic” has experienced some issues using our app. We can further click into Ado Kukic and see what errors he has experienced and when the last occurrence of the errors were.

Knowing which users were affected by errors in your application is invaluable for both diagnosis and public relations.

The raygunClient.user method allows you to specify which information about the user you would like to capture. The only required field is an identifier, so if you would prefer not to send potentially sensitive user information to Raygun but still would like to have some type of attribution of errors to user accounts, you can devise your own unique identifier and use that instead.

Conclusion

Raygun simplifies the process of tracking and diagnosing errors in your application. Today we integrated a simple Node.js application into Raygun. We showcased how Raygun can be an invaluable tool in diagnosing and tracking issues and errors with your application.

Raygun tracks both automatic and developer initiated errors. Additionally, Raygun’s user tracking system allows you to attribute errors to users for better diagnosis. Below is the full application we built that showcases different types of error that Raygun can handle.


// grab the modules we need
var express = require('express'),
    raygun = require('raygun');

// initiate a raygun client
var raygunClient = new raygun.Client().init({ apiKey: 'API-KEY-HERE' });

// get an instance of express for our application
var app = express();

// IMPORTANT: per Express and Raygun documentation, for Raygun to properly capture application based errors it's middleware will need to be called before the app.listen function
app.use(raygunClient.expressHandler);

// create the simple-error route
app.get('/simple-error', function(req, res){
    // create a new error object
    var err = new Error('Simple Error');

    // send that error off to raygun
    raygunClient.send(err);

    // send a message back to the browser
    res.send('Simple Error Thrown');
});

app.get('/app-error', function(req, res){
    // sunday is an undeclared variable
    var message = "Hello world! Today is " + sunday; 

    // send this message back to the client
    res.send(message);
});

// attach a user to a raygun error
app.get('/user-error', function(req, res){

    // create a raygun user
    raygunClient.user = function(req) {
        var user = {
            identifier: "<a href='mailto:ado@scotch.io'>ado@scotch.io</a>",
            fullName : "Ado Kukic",
            isAnonymous : false
        } 
        return user;
    }

    // create the error
    var err = new Error("User Tracking Error");

    // send the error
    raygunClient.send(err);

    // send info back to the browser
    res.send("User Tracking Error");

});

// start our app on port 8080
app.listen('8080');

Finding and fixing issues before users experience them is vital to a building an applications that users will come back to. Raygun will save you the headache of digging through hard to read server logs after an issue is reported by an unhappy user.

This post sponsored by via Syndicate Ads.