feat(issues): New stack trace component#109428
Conversation
- handles long filenames by wrapping to two lines - handles mobile screen sizes a little better - has two contexts instead of prop drilling - does not use global styles
Move frame context and variables rendering further onto layout/text primitives and wire frame context regions to chevron controls for better semantics. Avoid work for collapsed frames by gating source context/highlighting inputs behind expansion state. Add keyboard-focused tests for chevron Enter/Space behavior and aria wiring. Co-Authored-By: Claude <[email protected]>
Extract frame context and variables rendering into reusable stacktrace units and tighten header/layout interactions for the new component API. Add a coverage host that uses React Query query options and query cache, fetching coverage only for expanded frames while keeping the base StackTrace component data-source agnostic.
Fix Core StackTrace spec failures by adding default stacktrace-link mocks, making badge assertions resilient, and using explicit space key events for chevron keyboard behavior. Also remove unused stacktrace exports and simplify coverage query eligibility checks without changing behavior.
Lift toolbar view state (view, isNewestFirst, isMinified) out of per-exception StackTraceProviders into a single StackTraceSharedViewContext. ChainedStackTrace now renders one toolbar above all exceptions so switching App/Full/Raw or toggling order affects all frames simultaneously. - Add StackTraceSharedViewContext + StackTraceSharedViewProvider - StackTraceProvider.Root falls back to local state when no shared context is present (existing single-trace usage unchanged) - Toolbar sub-components read shared context first, then per-provider context, enabling standalone use in StackTraceSharedViewProvider Co-Authored-By: Claude <[email protected]>
mix-blend-mode: screen washed out coverage colors to near-white when blending against background.secondary (a light gray). The old component used var(--prism-highlight-background) which is dark enough for screen blending to produce visible results. Since FrameSourceLineNumber is a grid cell, its background already covers the row highlight naturally — no blending is needed. Remove mix-blend-mode and apply coverage colors directly, using the 200-level shades for active lines to distinguish from the 100-level shades on inactive lines. Co-Authored-By: Claude <[email protected]>
Pull all frame actions (chevron, source link, source maps debugger, hidden frames toggle) out of the monolithic FrameHeader into individual files under frame/actions/, mirroring the toolbar/ pattern. Expose them via StackTraceProvider.Frame.Actions.* so consumers can compose exactly the actions they need. FrameHeader gains an `actions` prop — when omitted it renders the same default set as before, so all existing usage is unchanged. Also extracts toolbar items (DisplayOptions, CopyButton, DownloadButton) into toolbar/, adds ExceptionHeader as a standalone composable component, and isolates hover state into a separate StackTraceFrameHoverContext so only action components re-render on hover rather than the full frame tree. Co-Authored-By: Claude <[email protected]>
…ckTrace Replace the standalone ChainedStackTrace component with IssueStackTrace, a single cohesive component that handles both single and chained exceptions. IssueStackTrace owns the InterimSection chrome (title, actions in header) for both cases and provides a CopyButton that concatenates all stacktraces in the chained case. Move SharedViewRoot out of stackTraceProvider into issueStackTrace so the provider stays a pure generic component with no knowledge of the issues layer. Remove StackTraceSharedViewProvider export entirely. Co-Authored-By: Claude <[email protected]>
Remove lockAddress and threadId from the generic StackTraceProvider context. These were ANR-specific concerns leaking into a generic component. Replace with a frameBadge render prop that lets callers inject per-frame badges without the provider knowing about ANR. IssueStackTrace now owns the ANR detection logic and passes a frameBadge callback that computes the Suspect Frame badge for qualifying frames. Also fixes the coverage line number aria-label for accessibility. Co-Authored-By: Claude <[email protected]>
…x minified story - Document all StackTraceProviderProps with JSDoc comments - Rename Display Options toggle from "Unsymbolicated" to "Minified" to match the internal value name and be more discoverable - Update the minified story to use StackTraceProvider directly with defaultIsMinified so the feature is visible on load Co-Authored-By: Claude <[email protected]>
Introduce a dedicated view-state provider and require stack-trace consumers to read from a single context source to remove cross-context fallbacks. Replace hover context with explicit props, tighten shared type contracts, and document context field guarantees so stack-trace APIs are easier to reason about. Co-Authored-By: Claude <[email protected]> Made-with: Cursor
Move frame expansion state out of shared stacktrace context so toggling one frame updates only per-row consumers. Also hoist project lookup to provider scope and use set-based index membership in row building to cut repeated per-frame work. Co-Authored-By: Claude <[email protected]> Made-with: Cursor
Restore StackTraceProvider.Frame to its public row-based API so composed frame stories compile without internal expansion props. Also remove a dead nullable context check in DownloadButton and align minifiedStacktrace docs with the new view-state provider model. Co-Authored-By: Claude <[email protected]> Made-with: Cursor
Split frame rendering and default actions into dedicated stack trace modules and update the frame header to rely on CSS truncation with selectable inline text. This keeps path suffixes visible, improves copy/paste behavior, and stabilizes single-line and wrapped alignment. Co-Authored-By: Claude <[email protected]> Made-with: Cursor
Use shared Text primitives and simplify inline metadata wrappers so the frame title row keeps consistent spacing and baseline alignment. Co-Authored-By: Claude <[email protected]> Made-with: Cursor
Render chevrons as non-interactive indicators and reserve slot width only when visible rows include expandable frames. Keep action columns aligned across mixed rows and add a Storybook example to verify the behavior quickly. Co-Authored-By: Claude <[email protected]> Made-with: Cursor
# Conflicts: # static/app/views/issueDetails/groupEventDetails/groupEventDetailsContent.tsx
malwilley
left a comment
There was a problem hiding this comment.
Some nits and questions but overall looks good 👍
| * Default trailing actions rendered for every frame row: | ||
| * hidden-frames toggle, repeated-frame badge, in-app badge, and chevron. | ||
| */ | ||
| export function DefaultFrameActions({isHovering: _isHovering}: DefaultFrameActionsProps) { |
There was a problem hiding this comment.
Do we want this barrel file? I thought we were against them
| border-radius: 0; | ||
|
|
||
| && { | ||
| white-space: pre-wrap; |
There was a problem hiding this comment.
I assume this is necessary because we have some styles in the less files?
There was a problem hiding this comment.
yeah seems like there's a code[class*='language-'] in global
There was a problem hiding this comment.
The context definitely makes things so much nicer to work with
|
|
||
| // Lazy: track frames that have ever been visible so we only mount on first appearance. | ||
| // A ref is sufficient — the component already re-renders when `rows` changes. | ||
| const everVisibleRef = useRef(new Set<number>()); |
There was a problem hiding this comment.
Was this used before or is this a new performance optimization?
There was a problem hiding this comment.
its new, i wanted to make them only render after being opened but its a little annoying that everything loses state when you toggle the frames open/close so there's this ref that preserves the state using react 19's activity https://react.dev/reference/react/Activity
might be overcomplicated
|
🚨 Warning: This pull request contains Frontend and Backend changes! It's discouraged to make changes to Sentry's Frontend and Backend in a single pull request. The Frontend and Backend are not atomically deployed. If the changes are interdependent of each other, they must be separated into two pull requests and be made forward or backwards compatible, such that the Backend or Frontend can be safely deployed independently. Have questions? Please ask in the |
static/app/views/issueDetails/groupEventDetails/groupEventDetailsContent.tsx
Outdated
Show resolved
Hide resolved
Replace rest-spread destructuring of the discriminated union props with direct narrowing on the props object, so TypeScript properly resolves values as ExceptionValue[] and stacktrace as StacktraceType in each branch. Remove the now-unused isStandaloneProps helper. Add EntryMap mapped type that maps each EntryType to its corresponding Entry subtype. Use it in eventEntries so lookups like eventEntries[EntryType.EXCEPTION].data.values resolve to ExceptionValue[] | undefined instead of any. Move the raw view early return above the single-exception branch so raw rendering is handled uniformly regardless of exception count. Add test covering raw view for single exceptions and type-level assertions for the component props. Co-Authored-By: Claude Opus 4.6 <[email protected]>
New stack trace component (non-native): - no longer uses a mix of emotion and global styles - [stories for many of the complex states](https://sentry-9kfjix4ca.sentry.dev/stories/product/components/stacktrace/stacktrace/) - A few contexts instead of prop drilling - Frame content does not render until opened, speeding up issue details render speed on large 100+ frame stack traces. - The regular opportunities that show up when re-writting, like using our <Grid> <Flex> components - Styles are no longer shared with native frames which has made them historically difficult to touch, since you had to look at the variations of regular errors and native errors. Components are now broken into IssueStackTrace and StackTrace. **All fetch requests** happen in IssueStackTrace and StackTrace components are somewhat designed to be compostable. It got tricky in there.
New stack trace component (non-native):
Components are now broken into IssueStackTrace and StackTrace. All fetch requests happen in IssueStackTrace and StackTrace components are somewhat designed to be compostable. It got tricky in there.
stories - https://sentry-9kfjix4ca.sentry.dev/stories/product/components/stacktrace/stacktrace/