Skip to content

Capturing Errors

Your web application is live, and your user base is growing every day. You want to make sure everyone of them have a flawless experience with your product and monitoring is here to help you achieve that. It’s hard and expensive to get everything right the first time, what matters is to be informed when errors occur and have sufficient context to help remediate them quickly.

These docs will help you get started with a simple setup that you can enhance as needed.

The first step is to start with your blind spots or what we call unexpected errors. I’m sure you’ve already seen the following error:

TypeError: Cannot read properties of undefined

The good news is that it’s relatively easy to get started here. There are multiple solutions on the market that help you capture unexpected errors out of the box by integrating their SDK.

In an entreprise context, I’ve been very happy using Sentry (I am not affiliated in any way). The main reason I would recommend Sentry is that it is both easy to get started with but also covers a wide range of monitoring and observability needs for modern frontend applications.

As engineers, we’ve been trained to manage failures and leave little to chance. That’s why you likely already handle most errors in your application code. What’s important is to also have visibility in how many times these errors occur to be able to react when they become “the norm”.

For example when you fetch data from an API:

try {
const response = await fetch(requestUrl);
const data = await response.json();
...
} catch (error) {
// What to do here?
// My recommendation: forward the error to your monitoring SDK
Sentry.captureException(error)
}
});

In such cases, it’s tempting to also log the error to the console but I never found a lot of value in doing that.

There is an entire class of errors I am tired to see inside monitoring tools and that you should treat differently. It’s what I would call “business expected errors”. It’s not technically an error as it’s a business requirements which was planned and mapped out. Here are a few examples I have encountered:

  • A request to a resource that no longer exists or for which the user does not have permission
  • A backend error to a form validation
  • A rate limt error

You might argue that some of those should never occur and can be prevented with better guardrails in your frontend application. You’d be right but that’s not always possible and this type of error will always exist and treating them as first-class citizens will help. Now the question becomes: what to do with those?

I would not treat them as regular exceptions but rather capture them as metrics for which you can set acceptable thresholds to alert upon. You will be fine having a few of those every now and then but you also don’t want them to create noise in your error reporting. This last part is critical as error monitoring noise is often the main reason that hinders team to get value out of their error monitoring tooling.

Below is an example of how I would treat a resource not found with Sentry metrics:

try {
const response = await fetch(requestUrl);
if (!response.ok && response.status === 404) {
Sentry.metrics.count("resource_not_found", 1);
}
} catch (error) {
Sentry.captureException(error);
}
});

This is also the reason I would recommend picking a solution that supports metrics reporting from the beginning.

Before we jump to alerting based on your error monitoring, here are my tips to get the most out of your error monitoring:

  • Start simple: integrate with a solution which provide a web or framework specific SDK
  • Discriminate between unexpected errors (unhandled exceptions), generic errors (handled expections) and business expected errors (expected business scenarios)
  • Unless you have specific events with high cardinality, I would not use logs for error monitoring as they are hard to filter and count through.