fix: improve Sentry issue grouping to eliminate duplicate issues#1028
Conversation
|
Codecov Results 📊✅ Patch coverage is 94.12%. Project has 4283 uncovered lines. Files with missing lines (2)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 81.95% 82.01% +0.06%
==========================================
Files 329 329 —
Lines 23749 23805 +56
Branches 15502 15543 +41
==========================================
+ Hits 19463 19522 +59
- Misses 4286 4283 -3
- Partials 1643 1641 -2Generated by Codecov Action |
5233957 to
eec7396
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit eec7396. Configure here.
| const kind = deriveErrorKind(error); | ||
| if (kind !== undefined) { | ||
| scope.setTag("cli_error.kind", kind); | ||
| } |
There was a problem hiding this comment.
Non-CliError errors through reportCliError miss kind tag
Low Severity
When a non-CliError exception (e.g., TypeError) is routed through reportCliError, deriveErrorKind returns undefined so cli_error.kind is never set on the scope. Then enrichEventWithGroupingTags in beforeSend can't help because its early-return guard sees cli_error.class already present and skips the event — including the new message-prefix logic. The same error type caught by the uncaught-exception handler would get cli_error.kind since cli_error.class isn't pre-set. This contradicts the PR's stated goal of zero error classes without cli_error.kind.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit eec7396. Configure here.
| result = result.replace(pattern, replacement); | ||
| } | ||
| return result.replace(BARE_NUMERIC_SEGMENT_RE, "/{id}"); | ||
| } |
There was a problem hiding this comment.
Duplicate exported normalizeEndpoint name across modules
Low Severity
A new exported normalizeEndpoint function is introduced in error-reporting.ts that parameterizes path segments for Sentry grouping, but src/commands/api.ts already exports a completely different normalizeEndpoint that normalizes endpoints for API requests (trailing slashes, prefix stripping). Two exported functions with the same name but very different behavior risk accidental misuse via auto-import.
Reviewed by Cursor Bugbot for commit eec7396. Configure here.
- Add cli_error.kind tags for CliError, HostScopeError, WizardError (previously had no grouping key, every unique message = separate issue) - Extract deriveErrorKind() from setGroupingTags() to reduce complexity - Add normalizeEndpoint() for ApiError sub-grouping by endpoint shape - Expand extractResourceKind() to strip 'in <slug>' and entity name slugs - Enrich non-CliError exceptions (TypeError, Error) with kind from message - Drop EBADF errors in beforeSend (same class of OS noise as EPIPE) - Add 34 new tests (unit + property) covering all new grouping logic
eec7396 to
300b2d0
Compare


Problem
The CLI's Sentry project had 300+ unresolved issues with ~30 duplicate groups caused by gaps in the fingerprinting system:
cli_error.kindtags —CliError(base),HostScopeError, andWizardErrorhad no grouping key, so every unique error message created a separate Sentry issuecli_error.classwith no kind tagextractResourceKind()didn't strip bare slugs (in my-org) or entity-name prefixed slugs (Organization my-company)Solution
Code changes (2 source files)
src/lib/error-reporting.ts:deriveErrorKind()fromsetGroupingTags()to reduce cognitive complexitycli_error.kindforHostScopeError(host_scope),WizardError(wizard), and baseCliError(4-word message prefix)normalizeEndpoint()— parameterizes variable API path segments, setscli_error.api_endpointtagextractResourceKind()— stripin <slug>(not justin org/project), strip hyphenated slugs after entity namesenrichEventWithGroupingTags()— setcli_error.kindfrom message prefix for non-CliError exceptionssrc/lib/telemetry.ts:isEbadfError()— detects EBADF errors (bad file descriptor from stdin reopen)beforeSend(same class of OS noise as EPIPE)Sentry project housekeeping (already done)
resolved in next release(EBADF ×3, replaceAll TypeError ×1)Tests
Expected Impact
cli_error.kind