Skip to content

feat: add error message normalization and integration#1718

Merged
morgan-wowk merged 1 commit intomasterfrom
01-26-feat_add_error_normalization_and_integrate
Feb 5, 2026
Merged

feat: add error message normalization and integration#1718
morgan-wowk merged 1 commit intomasterfrom
01-26-feat_add_error_normalization_and_integrate

Conversation

@morgan-wowk
Copy link

@morgan-wowk morgan-wowk commented Jan 28, 2026

Description

Implemented error message normalization for Bugsnag to improve error grouping. This enhancement extracts dynamic values (UUIDs, IDs, hashes) from error messages and replaces them with placeholders, allowing similar errors with different dynamic values to be grouped together.

The implementation includes:

  • A new normalizeErrorMessage utility that identifies and extracts common patterns
  • Enhanced Bugsnag error handling that applies normalization to generic Error instances
  • Custom grouping hash generation for better error categorization
  • Preservation of extracted values as metadata for debugging

Type of Change

  • Improvement
  • New feature

Checklist

  • I have tested this does not break current pipelines / runs functionality
  • I have tested the changes on staging

Test Instructions

  1. Verify that similar errors with different IDs/UUIDs are grouped together in Bugsnag
  2. Check that the extracted values are available in the error metadata
  3. Confirm that HTTP status codes are preserved and not normalized
  4. Ensure custom error classes (NetworkError, ValidationError, etc.) are not affected by normalization

Copy link
Author

morgan-wowk commented Jan 28, 2026

@morgan-wowk morgan-wowk force-pushed the 01-26-feat_add_bugsnag_error_reporting_service_v2 branch from 43d2c0a to a0597d8 Compare January 28, 2026 22:12
@morgan-wowk morgan-wowk force-pushed the 01-26-feat_add_error_normalization_and_integrate branch 2 times, most recently from b29beaf to 7dd0dc9 Compare January 28, 2026 22:16
@morgan-wowk morgan-wowk marked this pull request as ready for review January 28, 2026 22:19
@morgan-wowk morgan-wowk requested a review from a team as a code owner January 28, 2026 22:19
@morgan-wowk morgan-wowk force-pushed the 01-26-feat_add_error_normalization_and_integrate branch 3 times, most recently from f7acc67 to 0dcd36d Compare February 3, 2026 21:47
@morgan-wowk morgan-wowk force-pushed the 01-26-feat_add_bugsnag_error_reporting_service_v2 branch from a0597d8 to 5bdaabd Compare February 3, 2026 21:47
@morgan-wowk morgan-wowk force-pushed the 01-26-feat_add_error_normalization_and_integrate branch from 0dcd36d to c7d466b Compare February 3, 2026 21:49
@morgan-wowk morgan-wowk force-pushed the 01-26-feat_add_bugsnag_error_reporting_service_v2 branch 2 times, most recently from 4e541c5 to 88883ad Compare February 3, 2026 21:50
@morgan-wowk morgan-wowk force-pushed the 01-26-feat_add_error_normalization_and_integrate branch 2 times, most recently from 54c9881 to b717d56 Compare February 3, 2026 21:54
Copy link
Collaborator

@Mbeaulne Mbeaulne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

left a few non blocking comments

Comment on lines 30 to 48
if (event.errors[0].errorClass === GENERIC_ERROR_CLASS) {
const errorMessage = event.errors[0].errorMessage;
const { normalizedMessage, extractedValues } =
normalizeErrorMessage(errorMessage);

event.groupingHash = normalizedMessage;
event.errors[0].errorClass = normalizedMessage;

if (BUGSNAG_CUSTOM_GROUPING_KEY) {
event.addMetadata("custom", {
[BUGSNAG_CUSTOM_GROUPING_KEY]: normalizedMessage,
});
}

if (Object.keys(extractedValues).length > 0) {
event.addMetadata("extracted_values", extractedValues);
}
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember doing something similar in other codebases with event.errors[0] but I have lost all context. What happens of there are multiple errors? do we need to account for them?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some research, I learned that Bugsang supports multiple erorrs on an event but this is not really seen in Javascript / frontend apps. It would be seen for example in some backend applications that are explicitly tracking and reporting multiple errors to Bugsnag. I remember implementing this once in the past for an API endpoint that would perform multiple independent tasks and report errors from each in a single response.


type NormalizationReplacer = (
match: string,
...args: any[]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be unknown[] instead of any?

name: "uuid",
// Matches UUIDs in paths (e.g., /api/executions/019b3428-a0f0-d259-b764-ae0efbf37a64/status)
pattern:
/\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(\/|$|\)|\s)/gi,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we abstract this pattern out to a named variable? Looking at this regex I don't reallly know what it does. I get that there is a comment, but I wonder if we just remove the comment in place of a named variable.

const MATCH_UUID_IN_PATH = regex

Thoughts?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I switched to constants with as clear names as I could get. Seems reasonable!

{
name: "numericPathId",
// Matches numeric IDs in paths (e.g., /users/12345/profile)
pattern: /\/(\d+)(\/|$|\)|\s)/g,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done for all

name: "alphanumericPathId",
// Matches alphanumeric IDs in paths that are 6+ chars with both letters and digits (e.g., /files/abc123defghi/data)
pattern:
/\/([a-zA-Z0-9]*\d[a-zA-Z0-9]*[a-zA-Z][a-zA-Z0-9]{6,}|[a-zA-Z0-9]*[a-zA-Z][a-zA-Z0-9]*\d[a-zA-Z0-9]{6,})(\/|$|\)|\s)/g,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above

{
name: "queryParamId",
// Matches query parameter values that contain digits or are hexadecimal (e.g., ?id=abc123 or ?token=a1b2c3)
pattern: /([?&][a-zA-Z_]+)=([0-9a-zA-Z-]{6,})/g,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above

name: "hashOrDigest",
// Matches common hash lengths: MD5 (32), SHA-1 (40), SHA-256 (64)
// More specific than 16+ to avoid false positives with sequential numbers
pattern: /\b([a-f0-9]{32}|[a-f0-9]{40}|[a-f0-9]{64})\b/gi,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment as above

@morgan-wowk morgan-wowk force-pushed the 01-26-feat_add_error_normalization_and_integrate branch from b717d56 to e31158e Compare February 5, 2026 22:20
@morgan-wowk morgan-wowk changed the base branch from 01-26-feat_add_bugsnag_error_reporting_service_v2 to graphite-base/1718 February 5, 2026 22:30
@morgan-wowk morgan-wowk force-pushed the 01-26-feat_add_error_normalization_and_integrate branch from e31158e to 7560f78 Compare February 5, 2026 22:33
@graphite-app graphite-app bot changed the base branch from graphite-base/1718 to master February 5, 2026 22:34
@morgan-wowk morgan-wowk force-pushed the 01-26-feat_add_error_normalization_and_integrate branch from 7560f78 to 2671a92 Compare February 5, 2026 22:34
Add utility to normalize error messages by extracting dynamic values (UUIDs, IDs, hashes, etc.) and replacing them with placeholders. This enables better error grouping in monitoring tools like Bugsnag.

Integrate normalization into Bugsnag error handler with custom grouping hash.
@morgan-wowk morgan-wowk force-pushed the 01-26-feat_add_error_normalization_and_integrate branch from 2671a92 to 95adc7b Compare February 5, 2026 22:44
Copy link
Author

morgan-wowk commented Feb 5, 2026

Merge activity

  • Feb 5, 10:47 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Feb 5, 10:47 PM UTC: @morgan-wowk merged this pull request with Graphite.

@morgan-wowk morgan-wowk merged commit b333d3b into master Feb 5, 2026
8 checks passed
@morgan-wowk morgan-wowk deleted the 01-26-feat_add_error_normalization_and_integrate branch February 5, 2026 22:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants