Have you ever shipped a piece of code to production and then waited apprehensively to see if bug tickets rolled in?

Ever had a release that you thought was pretty solid until a day or two after deployment when users called in with long lists of confusing and contradicting error reports that seem impossible to reproduce?

I have, and I can tell you it’s not a fun place to be.

Thankfully, Raygun’s error tracking offering provides a saner way of keeping tabs on software quality – both before and after releases.

Disclaimer: While I have enjoyed great success using Raygun as a customer, this article is a paid article exploring setting up Raygun for exception logging purposes in your applications.

Overview

In this article I’ll give you a step-by-step tutorial to set up Raygun Error Tracking in a modern client-server single page application (SPA) project.

Specifically, we’ll build a simple calculator application in Angular that calls out to the server to perform actual calculations. You would never ever do this in production, but this allows us to illustrate error logging in multiple technologies.

I’ll be using .NET Core to serve up an Angular client-side SPA. We’ll use Raygun to track errors on the server in the .NET Core Web API and client-side in JavaScript.

Please note that the code in this article is not intended to represent code you should write – especially in a production environment. In fact, I’m intentionally making things that are easy to break so that we can see the exception management capabilities of Raygun.

Prerequisites

In order to log anything to Raygun, you will need to sign up for a free trial and create an account.

Thankfully Raygun supports Google Authentication so if you have a Google account, you can authenticate without having to come up with a new username and password combination.


If you want to follow along with the code, you’ll need Visual Studio 2019 Community installed on your machine.

You’ll want to make sure that the ASP.NET and web development workload is installed as well:

This should also install everything you need to do Angular development as part of Visual Studio.

Creating the Project

In Visual Studio, create a new project and give it an appropriate name:

When prompted to select an application type, choose the Angular template as pictured below:

After you click Create, Visual Studio will create a basic .NET Core application in C# that hosts an Angular single page application.

The Angular code is nested inside of the ClientApp directory. If editing Angular code inside of Visual Studio isn’t your thing, you can open this folder as an Angular project in another editor such as WebStorm or Visual Studio Code.

If you run the application now, you’ll get a boiler-plate web application in your browser with a page for weather information and a page with an Angular counter component.

Creating the Calculator API

Let’s start customizing this application by adding a new CalculatorController to our Controllers folder:

Here we added a series of HTTP GET endpoints for various simple mathematical operations: Add, Subtract, Multiply, Divide, and Power.

I’m going to gloss over the specifics of how this works since this article is more about learning Raygun’s capabilities than learning a specific technology.

That said, if you’d like to learn more about .NET Core API projects, check out my article on learning .NET Core API Development.

Testing the API

Before we move on to adding the Calculator user interface, let’s run Visual Studio and make a request to our new endpoint in Postman, a popular and free API testing tool.

Launch Postman and start creating a new GET request to the same URL as your Visual Studio project, but with /calculator/add/2/2 tacked on to the end as pictured below:

Clicking Send will send the request. If you ran the project in Visual Studio, the server will be online and hopefully respond with 4 in the response and a 200 OK response code as pictured above.

Creating the Calculator UI

Now that we have a working server, let’s add a new Angular component called calculator-component to represent it.

Here is the template we’ll use:

Since this template won’t do anything without the component being defined, let’s define it now:

This component is largely a property bag containing an XValue and a YValue as well as a Results string to display the calculation result to the user.

The click handlers all call out to a MathService which in turn makes HttpClient calls to our .NET Core Web API:

As part of this, we need to add our new component to app.module‘s declarations section and the service to its declaration section in order for Angular to recognize them at runtime.

Once this is done, you can either add a route to the new component, or just replace the router-outlet component in app.component.html.

I know I’m skimming a lot of the details and steps on Angular application development.

If you’d like to learn more about Angular, I recommend you check out Angular’s Tour of Heroes learning resources.

Trying it Out

Once all of this is done, the Angular application should be ready to run and talk to our .NET Core API.

Now, if we run our application and start typing in values, we’ll see responses come back:

Sure, the user interface and user experience are lackluster, but that’s not the point. The point here is that .NET Core is serving up an Angular application which is then calling out to the .NET Core’s API and doing something with its response.

In my book, that’s pretty cool.

What’s less cool is that the code above is having some blatant issues as illustrated in the graphic above.

For example, neither the client-side JavaScript or the server-side C# are handling bad inputs. If I try to divide by zero, I get a server-side error and no response is displayed. Similarly, if I type in something other than a number, I also get an error.

If I were to deploy this application, I would only hear about these errors if an end user experienced them, decided to tell me about them, found some contact information, and then took the time to actually get in touch.

That’s no way to deliver quality software. Let’s add Raygun and start logging our errors.

Adding Client-Side Error Tracking

While Raygun offers a generic JavaScript error logging script, we want to use the one specifically built for Angular since it properly hooks into the framework’s error handling process.

Note: Raygun gives us all of the following steps during setup, so don’t stress these steps too much.

To start, we need to run npm i raygun4js --save to install and save the raygun4js dependency in a way that will include it in the compiled JavaScript.

Next, we’ll need to add a new class to act as an error handler:

This ErrorHandler will call out to rg4js to send error details, but it will not be used unless we register it as Angular’s error handler.

We do this by modifying the providers in app.module.ts like so:

  providers: [
    MathService,
    {
      provide: ErrorHandler,
      useClass: RaygunErrorHandler
    }
  ],

Now that this is done, when Angular needs an ErrorHandler, it will grab our custom-made RaygunErrorHandler to do the job and send on error details to Raygun.

Adding Server-Side Error Tracking

Next, let’s look at the client-side .NET code.

Raygun offers a wide variety of NuGet packages for the various flavors and versions of .NET applications.

To get started, right click on your project in Solution Explorer and click Manage NuGet Packages… as pictured below:

Next, click Browse and search for Raygun.

Since we’re using .NET Core, we’ll select Mindscape.Raygun4Net.AspNetCore and install that version as pictured below:

This installs the library dependency that we need in order to reference Raygun, but does not hook Raygun up to our application yet.

Let’s do that now by going into Startup.cs.

At the top of the file, we’ll add the following using statement:

using Mindscape.Raygun4Net.AspNetCore;

Next, at the bottom of the the ConfigureService method, add the following code:

// Allow Raygun to register needed components / services
services.AddRaygun(Configuration);

After that, add the following code to the Configure method:

// Tell Raygun that we want it to log exceptions
// NOTE: This normally should only be used set if env.IsDevelopment() is false
app.UseRaygun();

We’ll keep this UseRaygun call outside of the production-only code for now as we want to test Raygun in development before disabling it on development machines.

Finally, we need to tell Raygun about our API Key in our appsettings.json file by adding the following section:

  "RaygunSettings": {
    "ApiKey": "YourApiKeyGoesHere",
    "ApplicationVersion": "1.0.0.1"
  }

Looking at Exceptions

Now if we try to use the same sort of bad inputs and then look at Raygun, we’ll see some exceptions come in:

In the list of errors, the first one represents the error on the server side in .NET and the second is the client-side JavaScript in the Angular application logging the failure of the HTTP GET call.

We’ll take a look at each error in turn.

Server Side Error Details

If we drill into a server error instance, we get details that look something like this:

This is helpful stuff!

Right away you see the version number of the application, the error message, and a stack trace telling you exactly where the error was thrown.

Raygun also provides helpful context on the error in the sidebar, including number of occurrences, when it first appeared, and current status and assignee.

Since this is an error related to a web request, we can go into the HTTP tab and get details like the following:

That’s a whole lot of information. Sure, some of it like cookie values are noise, this does give us information on the exact request that came in, the browser requesting it, and the full URL used to contact the API.

In our case, this URL contains the route parameters used to perform the calculation and we can clearly discern from that that some user is trying to add 2 and “Doggo” together, leading to the error.

JavaScript Error Details

Because we’re also logging JavaScript errors on the client-side, we also see this JavaScript error logged on the Angular service as an error response:

In this case, because the error is ultimately occurring on the server side, this error isn’t as useful, but imagine you were calling out to an external API or the API you were calling was down. In these cases, it can be helpful to have error logging on the client side (in addition to logging non-API related errors as well).

Managing Errors

Next, let’s look at the process of fixing and releasing the error encountered.

First, let’s mark the errors as assigned to a specific user to investigate and resolve.

Next, you’ll look over the error details and attempt to replicate the errors locally.

Bear in mind that with Raygun you can put in additional context information in your code that might help you understand more about error requests.

In this particular case, all we really need is to see the URL ends with /calculator/add/2/Doggo to understand that Doggo is not something that will ever be able to be parsed to a number.

In this case, the request is a bad request, but the server is not validating its parameters (something that is very dangerous to do). Part of a fix for us should be to have the server validate the input parameters and return a 400 Bad Request response instead of throwing an exception trying to parse a bad input and logging that error.

We’ll change our API methods to validate input and explicitly return Ok and BadRequest responses:

Once we make the change, if we simulate the same request in Postman, we get a 400 Bad Request result with a meaningful error as pictured below:

Now that we have a fix ready for the server-side error, we can set it as Resolved in Raygun, or specify that it will be resolved in a specific version as pictured below:

This lets us ignore future errors until the new version is released with our fix. If the error ever recurs with a newer version, the Raygun error will no longer be ignored.

This keeps Raygun errors relevant and reduces noise from issues you’ve already solved but haven’t released to users yet.

In .NET Core, the best way of tracking your Raygun application version is to add it to your JSON file as follows:

  "RaygunSettings": {
    "ApiKey": "YourApiKeyGoesHere",
    "ApplicationVersion": "1.0.0.1"
  }

Now if you retry sending a bad request, you’ll see a 400 Bad Request come back, which will be logged as a JavaScript error to Raygun, but the server-side error is no longer resolved since a Bad Request response comes back instead of an unhandled error.

From here we can add client-side validation on the text box and not make API requests for non-numeric values. Alternatively, we could just constrain the text boxes to be of numeric type using HTML5.

Either way you go, the focus of this article is on Raygun, so we’ll not get into the particulars of those fixes.

The Utility of Raygun Error Tracking

What you’ll ultimately find with Raygun is an ability to make intelligent decisions based on errors coming in.

For example, imagine running a Software as a Service organization and getting an error report from a user via your support department. That report makes its way to product management and development and in that moment you have some key decisions to make.

Typically you’ll be wondering the following things:

  • What did the user do to encounter this problem?
  • How severe is this problem?
  • How frequently does this problem occur?
  • What percentage of users does this problem affect?
  • What do I need to do to recreate this?
  • Is this browser-specific? Data specific?
  • How urgent is this?

By using the error details, automatic error grouping, and error graphing, you can quickly make these types of decisions from Raygun:

As a direct benefit you are now:

  • Solving the highest priority problems first
  • Able to have enough information to recreate error details
  • Able to look up specific errors encountered by a particular user
  • No longer stressing out your development team by assuming that minor errors are severe site-wide errors impacting all users
  • Intelligently respond to accusations of poor quality with raw data

Raygun is also fantastic for finding errors early on after a deployment or even in quality assurance or preview environments.

By relying on Raygun, you can have confidence in code that isn’t even released yet and can quickly find and resolve configuration issues during deployments gone bad.

I personally can vouch that exception tracking has prevented troubleshooting botched deployments from going late into the evening, and even saved entire software releases.

Error Monitoring in other Technologies

Although I’ve highlighted .NET Core and Angular in this article, Raygun supports a wide variety of different application frameworks. including:

  • Generic JavaScript
  • PHP
  • Swift
  • Ruby
  • Java
  • Unity
  • Universal Windows Applications
  • Xamarin

Additionally, if a language you like somehow isn’t supported, you can still manually implement things by making API calls out to Raygun following their excellent documentation.

Speaking of documentation, the getting started process is fantastic. You simply select your preferred language and then follow the recommended steps from Raygun’s inline documentation:

These code snippets conveniently already include your project’s API Key, so you really can just copy and paste.

And, if you ever want to customize things by having custom additional data or tags to Raygun, the documentation is amazing there as well.

Take a look at the documentation on .NET Core and Angular to see the degree of quality I’m talking about.

Pairing with other Raygun Offerings

Raygun’s unique value proposition, in my opinion, is that it’s not just about crash reporting.

Raygun also offers products integrating real user monitoring features allowing you to get more information on the quantity and geographical distribution of your users. This can highlight problem areas as shown below:

There’s a lot more to it than this, but this article is focused on Raygun’s Crash Monitoring capabilities.

Additionally, Raygun also offers application performance monitoring (APM) solutions for .NET related technologies (at the time of this writing) which can highlight slow areas in your code, allowing you to improve your code’s performance and make intelligent decisions around performance.

Final Thoughts

Overall Raygun is a well-polished error management solution designed to make enterprise application development teams more equipped to handle errors of any type on any platform.

I have a high degree of confidence that adding Raygun to your stack will help you understand application and user behavior in a way that you haven’t experienced before.

Additionally, by surfacing errors as they happen and providing details on reproducing and resolving them, Raygun equips engineering teams to improve the overall application quality in a short period of time.

Give a free trial a try and see what Raygun can tell you about your applications.