Skip to content

feat(client): show full error message on hover in analytics recent errors table - #489

Open
jasnoorgill wants to merge 1 commit into
tashfeenahmed:mainfrom
jasnoorgill:feat/analytics-recent-errors-hover
Open

feat(client): show full error message on hover in analytics recent errors table#489
jasnoorgill wants to merge 1 commit into
tashfeenahmed:mainfrom
jasnoorgill:feat/analytics-recent-errors-hover

Conversation

@jasnoorgill

Copy link
Copy Markdown
Contributor

Summary

In the analytics Recent errors table, the message column was being
silently truncated by the existing truncate class on the <td> — operators
had no way to read the rest of the error string when a single row contained a
multi-line or long upstream error. Wrap the cell content in the existing
portal HoverTooltip so the full text is one hover (desktop) or tap-focus
(mobile) away, while the visible cell continues to clip with ... exactly
as before.

Motivation

The <td> already uses text-xs max-w-[200px] truncate, which is the
correct and desired on-screen behaviour — long error strings should not
overflow into the timestamp column. But the truncation is a one-way gate:
the operator can't recover the rest of the message from the dashboard.

Operators working on a long-tail error investigation need to see the full
error string (e.g. to distinguish a Cloudflare 600s-edge truncation from a
genuine upstream 4xx). Today they have to read the SQLite requests table
directly. A portal tooltip on the existing truncated cell closes the gap
without changing the table's layout or column proportions.

Changes

Single file, single cell, +3 / -1:

- <TableCell className="text-xs max-w-[200px] truncate">{e.error}</TableCell>
+ <TableCell className="text-xs max-w-[200px] truncate">
+   <HoverTooltip text={e.error ?? ''} side="top">{e.error}</HoverTooltip>
+ </TableCell>
  • Reuses client/src/components/tooltip.tsx — the same portal Tooltip
    already imported as HoverTooltip on line 12 of AnalyticsPage.tsx and
    used elsewhere on the page (stat-card hints at line 143).
  • No CSS changes. The <td>'s truncate class still does the clipping;
    the <span> rendered by HoverTooltip is the cell's only child, so the
    ellipsis still fires correctly.
  • side="top" keeps the tooltip inside the visible viewport even when the
    row is in the bottom half of the max-h-[240px] scrollable container.
  • Mobile gets the long-press behaviour for free: tapping the cell focuses
    the <span> (HoverTooltip already binds onFocus/onBlur), which
    triggers the same tooltip.

Why HoverTooltip and not a popover library

The project doesn't have Radix / HeadlessUI / shadcn-popover installed.
Adding one would be a ~50KB dependency for a single tooltip use-case. The
in-tree Tooltip component is already used in AnalyticsPage.tsx and
covers the requirements (hover, focus, portal positioning, viewport clamp).

Test plan

  • cd client && npx tsc -bTypeScript: No errors found
  • cd client && npm run build✓ built in 11.18s
  • Verified the tooltipped cell ships in the new bundle:
    grep -oE 'max-w-\[200px\][^"]*truncate' client/dist/assets/index-*.js
    returns the expected pattern with side:\top`andtext:e.error`.
  • Manual smoke test on the running service: an analytics row with a 200+
    character error string now shows the first ~200 chars with ... and
    reveals the full string on hover (or tap-focus on mobile).

Compatibility

Client-only change, no server impact, no DB migration, no i18n string
added. Safe to backport. No public API surface change.

Notes

References operator session 2026-07-07. No upstream issue number yet —
happy to file one if requested.

Wrap the (already truncated) message cell in the portal HoverTooltip so the
full error text is one hover/tap-focus away. No CSS changes — the existing
truncate on the <td> still does the clipping.
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.

1 participant