It’s common to have JavaScript error messages that are almost identical, but differ by a url segment or identifier. These can be noisy, creating dozens (or hundreds) of different groupings for the same bug. To clean this up, we’ve introduced Grouping Rules that allow you to define your patterns and find the real problems fast.

For example, imagine you have an endpoint which is experiencing errors.

500 Internal Error: GET /employees/123/roles

It’s great that we’re warned about the issue, but you’ll notice the url is present in the error message. Unfortunately, if this particular endpoint is broken for all employee IDs, you’ll start getting different messages for the same issue:

Multiple error messages for a similar error

This leads to high levels of noise, and many frameworks will include unique identifiers in an otherwise identical message. It makes getting an accurate count of the users affected more challenging too.

A few weeks ago we soft launched a feature we think will fix this pain point: Error Groupings.

Taking the example above, imagine we want to group the error messages so they show up as a single “message”. They are identical except for the employee ID segment.

Pattern Replacements

What we really want is some kind of named replacement token that becomes a placeholder for the employee ID segment. Something like:

500 Internal Error: GET /employees/${employeeId}/roles

This way regardless of ID, we’d only get a single message. Fortunately, this is exactly what you can do with Error Groupings in TrackJS today. When you create a new rule, you can specify these kind of replacements, as well as see which errors your pattern matches, or test a specific error against the pattern.

Creating a new error grouping

You can think of the ${employeeId} as a lazy wildcard regex like (.)*. Now when errors come in with an employee ID segment, they’ll match the grouping rule and the message will be re-written to that of the group.

500 Internal Error: GET /employees/${employeeId}/roles

Don’t worry though, we still retain the original message for when you drill in to the error details screen.

Showing both grouping and original message

Named Replacements

We call the replacement pattern above a named replacement. You can use whatever you want for the “name.”

Cannot read property ${propertyName} of undefined
${function name} is not a function

And you can use more than one replacement if you wish.

500 Internal Error: /customer/${customerId}/jobs/${jobId}/invoices/${invoiceId}

Hidden Replacements

There is a second type of replacement pattern we support. It is called a hidden replacement and looks like ${}. Yep, it’s an empty named replacement. The difference between a named and hidden replacement is that a hidden replacement removes the text it replaces from the message. Why is this useful?

There are two major scenarios. The first is that error messages are not always normalized across browsers. For example, Script error is a very common message, but so is Script error. (note the period at the end). If you want to match both messages, you can use the following:

Script error${}

The other useful scenario is to simply truncate long and noisy error messages. Some frameworks like to put stack traces or JSON blobs inside the message. It can be useful to trim these a bit. Here’s a before-and-after of a Mixpanel error.

A long and ugly error message


    ${}Implementation error. Please contact${}

which is rendered as

A trimmed and more readable version

Creating new groups

It would be painful to create every group from scratch, so we provide you with suggestions for groups that might be useful. It’s also possible to create a group from the messages tab directly.

Example Suggestions

What about Urls?

Noisy messages are an issue, but urls are almost guaranteed to benefit from grouping as well. We fully support groups for urls as well, and our suggestions are for both. There’s also a quick shortcut to create groups from the Messages and Urls tab…

Shortcut to create a group

We think this feature will help people keep noise down, and focus more on finding and fixing errors. If you have any comments or suggestions please let us know!