Add Sentry Error Intelligence dashboard with Slack search#1035
Add Sentry Error Intelligence dashboard with Slack search#1035liamdebeasi wants to merge 23 commits into
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Builder reviewed your changes and found 5 potential issues 🔴
Review Details
Code Review Summary — PR #1035: Sentry Error Intelligence Dashboard
This PR adds a new "Sentry Error Intelligence" dashboard to the analytics template with rich error analysis, escalation detection, and enhanced Slack/GitHub integration. The feature includes:
- New
sentry-errorsdashboard with top-10 error analysis, escalation detection, and related error grouping - Sentry org slug support via new data source field for proper multi-org configuration
- Enhanced Slack search with optional user-token support and intelligent fallback (fuzzy search with bot token)
- GitHub blame integration exposing commit history and contributor context for errors
- Thread enrichment fetching full Slack conversation context alongside search results
Architecture Assessment: The implementation is well-structured with proper separation of concerns (UI components, actions, server-side integrations), appropriate credential handling, and good error fallback patterns. Type safety is solid throughout.
Risk Classification: Standard risk (analytics feature addition, no breaking API changes, no database schema modifications).
Key Findings
Critical Issues: 🔴
- Missing function import breaks Slack user-token search (ReferenceError at runtime)
Should-Fix Issues: 🟡
- GitHub blame feature shipped but not integrated into the dashboard UI
- Slack secondary-workspace searches use wrong user token credential
- Sensitive Slack search content and queries leaked to server logs
- Slack URL matching has trailing-slash normalization issue
- Unused Sentry stats query adds unnecessary API overhead
Positives: ✅
- Proper credential scoping and access control
- Well-designed async error handling and fallbacks
- Correct React patterns (memoization, hook dependencies)
- Thoughtful API integration (Slack, GitHub, Sentry)
🧪 Browser testing: Will run after this review (PR touches UI code)
| // Prefer a user token (xoxp-) for search.messages if one was configured. | ||
| const userToken = await resolveCredential("SLACK_USER_TOKEN", ctx); | ||
| if (userToken) { | ||
| const params = new URLSearchParams({ |
There was a problem hiding this comment.
🔴 ReferenceError: resolveCredential not imported in searchMessages
The searchMessages function calls resolveCredential("SLACK_USER_TOKEN", ctx) on line 335, but this function is no longer imported. The import was changed to only resolveAnalyticsProviderCredential. This will cause a ReferenceError at runtime when Slack user-token search is attempted, crashing the entire search flow. Either reimport resolveCredential from "./credentials" or replace the call with resolveAnalyticsProviderCredential().
Or react with 🚀 to auto-fix.
| </span> | ||
| </div> | ||
|
|
||
| <SlackMentionsPanel issue={issue} /> |
There was a problem hiding this comment.
🟡 GitHub blame feature not mounted in the dashboard
The PR adds GitHubBlamePanel component and github-blame action, but IssueDetail only renders SlackMentionsPanel. The new GitHub blame feature is unreachable from the dashboard, making it a non-functional addition. Import and render GitHubBlamePanel alongside the Slack panel to complete the feature.
Or react with 🚀 to auto-fix.
| const ctx = requireRequestCredentialContext(botEnvKey); | ||
|
|
||
| // Prefer a user token (xoxp-) for search.messages if one was configured. | ||
| const userToken = await resolveCredential("SLACK_USER_TOKEN", ctx); |
There was a problem hiding this comment.
🟡 Secondary workspace uses same user token as primary
The searchMessages function prefers SLACK_USER_TOKEN for both primary and secondary workspaces. Since only one user-token credential was added (no SLACK_USER_TOKEN_2), secondary workspace searches will query the wrong Slack workspace when a user token is configured. Add per-workspace user-token support (SLACK_USER_TOKEN_2) or disable the user-token path for secondary workspace queries.
Or react with 🚀 to auto-fix.
| .split(/\s+/) | ||
| .filter((t) => t.length > 2); | ||
|
|
||
| console.log("[slack-search] query:", query); |
There was a problem hiding this comment.
🟡 Sensitive Slack content leaked to server logs
The fallback Slack search path logs raw search queries, channel names, and the first 80 characters of matched message text (lines 366, 393, 436). This exposes sensitive workspace content to server logs and any connected observability provider. Remove these logs or gate them behind a production-disabled debug flag. Never log raw message snippets.
Or react with 🚀 to auto-fix.
| name: string; | ||
| text: string; | ||
| ts: string; | ||
| channelName?: string; |
There was a problem hiding this comment.
🟡 Slack URL search missing trailing-slash normalization
The Slack search query includes the Sentry issue permalink, but the fuzzy matcher in slack.ts explicitly rejects URLs unless they match exactly. If the URL has trailing-slash variations (e.g., ...issues/123 vs ...issues/123/), the search will fail silently. Normalize the permalink URL to a canonical form before adding it to the search query (strip trailing slashes consistently).
Or react with 🚀 to auto-fix.
There was a problem hiding this comment.
Browser testing: 13/15 passed, 2 failed
Test Results: 13/15 passed ⚠️
✅ TC-01: Sentry Error Intelligence dashboard loads at correct URL (succeeded)
URLs tested: http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 2 screenshots captured
✅ TC-02: Period filter tabs (24h/7d/14d/30d) are visible and can be switched (succeeded)
URLs tested: http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 3 screenshots captured
✅ TC-03: Four stat cards are visible with correct labels (succeeded)
URLs tested: http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 2 screenshots captured
✅ TC-04: Correct error state is displayed when no Sentry credentials configured (succeeded)
URLs tested: http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 1 screenshot captured
✅ TC-05: Dashboard is listed in sidebar and sidebar navigation works (succeeded)
URLs tested: http://127.0.0.1:8080/analytics, http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 2 screenshots captured
✅ TC-06: Issues list renders correctly with mock data (succeeded)
URLs tested: http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 2 screenshots captured
✅ TC-07: Clicking an issue expands the detail view with metadata (succeeded)
URLs tested: http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 2 screenshots captured
✅ TC-08: Sparkline charts render in issue rows when stats data is present (succeeded)
URLs tested: http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 2 screenshots captured
✅ TC-09: GitHub blame panel is NOT rendered in the issue detail view (known bug verification) (succeeded)
URLs tested: http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 2 screenshots captured
✅ TC-10: Issue classification badges are shown correctly for different error types (succeeded)
URLs tested: http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 1 screenshot captured
✅ TC-11: Error Groups tab groups issues by error type with expand/collapse (succeeded)
URLs tested: http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 3 screenshots captured
❌ TC-12: Slack mentions panel renders in issue detail and initiates search (failed)
Steps: Navigated to Sentry dashboard with mock issues, expanded the first issue detail, found the pre-filled Slack query button, clicked it, waited, inspected DOM for visible changes, checked console for errors.
Failure: assertion_failed — After clicking the prefilled Slack search query button, the Slack mentions panel showed no visible response — no loading skeleton, no error message, no empty state. Expected: a user-friendly result (e.g., 'Slack is not connected' or 'No messages found'). The mutation may be silently failing or the response (likely 'missing_api_key' error code) is being shown in a non-visible part of the UI. No ReferenceError/crash was observed.
URLs tested: http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 3 screenshots captured
❌ TC-13: Data sources page shows Sentry "Not configured" and opens config dialog (failed)
Steps: Navigated to /analytics/data-sources, found Sentry under ENGINEERING section (Not configured), clicked it to open config flow, advanced to auth token step, searched DOM text for SENTRY_AUTH_TOKEN string.
Failure: assertion_failed — The Sentry configuration dialog under Data Sources shows "Enter your Auth Token" with placeholder "sntrys_..." but never mentions the environment variable name SENTRY_AUTH_TOKEN. The dashboard error state explicitly says "Add SENTRY_AUTH_TOKEN in Settings → Data sources", creating a terminology mismatch. The config panel does appear and accept a token correctly — just lacks the env var label.
URLs tested: http://127.0.0.1:8080/analytics/data-sources
Evidence: 3 screenshots captured
✅ TC-14: Escalating tab shows correct empty state when no escalating issues (succeeded)
URLs tested: http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 2 screenshots captured
✅ TC-15: Other adhoc dashboards still work after registry change (regression) (succeeded)
URLs tested: http://127.0.0.1:8080/analytics, http://127.0.0.1:8080/analytics/adhoc/test-dashboard-b-1778877310827, http://127.0.0.1:8080/analytics/adhoc/explorer, http://127.0.0.1:8080/analytics/adhoc/sentry-errors
Evidence: 4 screenshots captured
Details
PR #1035 Sentry Error Intelligence Dashboard: 13/15 tests passed. Core navigation, period tabs, stat cards, error states, issue display, sparklines, classification badges, escalation detection, Error Groups tab, and regression coverage all passed. Two failures: (1) Slack mentions search showed no visible feedback after activation — the search button click did not surface any result/error state in the UI; (2) Sentry config panel does not mention SENTRY_AUTH_TOKEN by name, creating a UX inconsistency with the dashboard error message. Additionally, TC-09 visually confirmed the known PR bug: GitHubBlamePanel.tsx exists but is never imported or mounted in the dashboard.
Summary
Adds a new "Sentry Error Intelligence" dashboard that surfaces top errors, escalating issues, and related error groups. Enhances the Slack integration with thread enrichment, fuzzy search, and user token support, and extends the Sentry data source to require an org slug.
Problem
There was no dedicated app for analyzing Sentry errors beyond what the official Sentry UI provides. Additionally, the Sentry data source lacked an org slug configuration field, and the Slack search integration only supported a bot token (which cannot use the
search.messagesAPI) and did not surface thread context or clickable message links.Key Changes
sentry-errorsdashboard registered in the adhoc dashboard registry (ErrorGroupsPanel.tsxand related components) with top-10 error analysis, escalation detection, related error grouping, and project filteringSENTRY_ORG_SLUGdata source field added to the walkthrough steps so users can configure their org slug via the UIgetCodeMappingsadded to the Sentry server lib and exposed as a newcode-mappingsmode in the Sentry actiongithub-blameaction added to fetch Git blame for a file path via GitHub's GraphQL APISLACK_USER_TOKENdata source field added as an optional walkthrough step (with an "Add" button replacing the static "Optional" label in the connected view)searchMessagesoverhauled: prefers a user token (xoxp-) forsearch.messages; falls back to bot-token channel history scanning with fuzzy matching (URL normalization, numeric suffix matching, prefix matching)enrichWithThreads) fetches full reply threads for matched Slack messages so conversation context is surfaced alongside search resultsresolveUsernamecan fall back to theusernamefield populated by the search APITo clone this PR locally use the Github CLI with command
gh pr checkout 1035You can tag me at @BuilderIO for anything you want me to fix or change