Skip to content

fix(hub-ui): show failed icons and retry on remount - #381

Open
dvcolomban wants to merge 5 commits into
devframes:mainfrom
dvcolomban:dvcol/fix-icon-retries
Open

fix(hub-ui): show failed icons and retry on remount#381
dvcolomban wants to merge 5 commits into
devframes:mainfrom
dvcolomban:dvcol/fix-icon-retries

Conversation

@dvcolomban

@dvcolomban dvcolomban commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Background (Why)

HTTP errors from Iconify were cached as successful SVG content, leaving blank dock icons. Rejected requests already leave the cache so a later mount can try again.

Changes (What)

Reject unsuccessful HTTP responses before caching, preserving the existing SVG sanitization. Show a bundled, color-inheriting fallback after failure and ignore results from obsolete component requests. Keep the existing shared requests and 10-second timeout; retry on the next mount or icon change.

Verification (Testing)

All 85 existing hub-ui tests, affected lint and type checks pass after simplification. Earlier browser validation covered request failures, shared caching, remount recovery and stale/unmounted components; its temporary harness is excluded from this PR.

The screenshots capture a forced HTTP 503 with Settings still usable, followed by recovery after reload with a deterministic SVG response. Screenshot evidence is stored separately from this PR.

Failed request with Settings usable

Recovered icon after reload

Copilot AI lite review requested due to automatic review settings September 10, 2026 16:46
@coldtea-pr-lens

coldtea-pr-lens Bot commented Sep 10, 2026

Copy link
Copy Markdown

◈ PR Lens

🟢 +0 new · 🟠 ~3 changed · 🔴 -0 removed · 1 flow · 2 files · commit 9ffadff


Architecture

Architecture diagram for devframes/devframe at 9ffadff

3 components touched across 2 lanes.

Open the interactive canvas


Inside the changed components — 1 view

Component view — Iconify rendering & caching

Component modules for icon fetching, status validation, and error glyphs

Architecture view of Component view — Iconify rendering & caching in devframes/devframe

Data flow

Data flow diagram for devframes/devframe at 9ffadff

Loading an icon with error fallback

Open the interactive canvas


View

  • Architecture lens
  • Data flow lens
  • Expand every detail

Tip

Run npx @coldtea/pr-lens-cli analyze --base origin/main on a branch, then npx @coldtea/pr-lens-cli render .pr-lens/graph.json. Same lenses, your own model key, before the pull request exists.

🪧 More tips
  • Run npx skills add coldteadotai/pr-lens, then tell your coding agent: "Diagram the change you just made with PR Lens and attach it to the pull request."
  • Untick Architecture lens or Data flow lens under View to hide a diagram, or tick Expand every detail to open every section. The comment redraws in a few seconds.
  • Click the link under each diagram to open it on a canvas you can zoom, pan and step through.
  • The diagrams are links. Click one to open it on the canvas, then press W or click play to walk through the change.
  • Open a diagram on the canvas, then press W or click play to walk through the change one step at a time.
  • The CLI's render reads .github/pr-lens.yml and applies your renames, exclusions and lane pins at draw time.
  • Set github.comment.collapsed: true in .github/pr-lens.yml to fold the comment behind one View architecture and data flow row. Drawing still runs on every push.
  • Add .github/workflows/pr-lens.yml with coldteadotai/pr-lens/packages/action@v0 and your model provider's key as its api-key to run PR Lens from your own CI. Any /chat/completions endpoint works.
  • Push a commit and the comment redraws for the new head. A slow older run never overwrites a newer one.
  • Switch GitHub to dark mode and the diagrams follow. The moving dots are this pull request's data in motion.

Thanks for using PR Lens! It's built by Coldtea, free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

@vercel

vercel Bot commented Sep 10, 2026

Copy link
Copy Markdown

@dvcolomban is attempting to deploy a commit to the NuxtLabs Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The changes directly address the stated failure modes, include targeted regression tests (including real mounted component behavior), and don’t introduce obvious correctness or safety regressions in the reviewed code paths.

Pull request overview

This PR improves the hub UI’s remote Iconify icon loading so transient failures don’t permanently blank mounted dock icons, and so non-OK HTTP responses/invalid SVG bodies aren’t cached as if they were valid icon content.

Changes:

  • Added retry logic for transient network/timeout errors and retryable HTTP statuses (408/429/5xx) while sharing in-flight work across concurrent consumers.
  • Sanitized and validated fetched SVGs before caching, and ensured failures are evicted so later renders can retry.
  • Added jsdom-backed regression tests and a per-package Vitest config to exercise mounted Vue behavior and stale-response handling.
File summaries
File Description
pnpm-workspace.yaml Adds jsdom to the shared testing catalog for consistent workspace resolution.
pnpm-lock.yaml Locks jsdom and related transitive dependencies and updates Vitest optional dependency graph accordingly.
packages/hub-ui/vitest.config.ts Introduces hub-ui’s Vitest project config (Vue SFC plugin + workspace aliases).
packages/hub-ui/src/client/utils/iconify.ts Implements retry + status handling and SVG sanitize/validate-before-cache behavior.
packages/hub-ui/src/client/utils/iconify.test.ts Adds regression tests for retries, caching/eviction, sanitization, and mounted component recovery.
packages/hub-ui/src/client/components/icons/IconifyIcon.vue Prevents stale async icon loads from updating state after unmount or icon changes.
packages/hub-ui/src/client/components/icons/IconifyIcon.test.ts Tests stale-response suppression when the icon prop changes mid-flight.
packages/hub-ui/package.json Adds jsdom as a dev dependency for hub-ui’s jsdom-based tests.
Review details

Files not reviewed (1)

  • pnpm-lock.yaml: Generated file
  • Files reviewed: 7/8 changed files
  • Comments generated: 0
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The changes align with the stated intent, appear safe for runtime usage, and are backed by targeted regression tests; only minor consistency/cleanup nits were identified.

Review details

Files not reviewed (1)

  • pnpm-lock.yaml: Generated file

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

packages/hub-ui/src/client/components/icons/IconifyIcon.vue:31

  • iconifyLoaded.value is set to undefined at the start of the effect, so the extra assignment in the !iconifyParsed early-return branch is redundant.
    packages/hub-ui/vitest.config.ts:9
  • In this repo, other Vitest project configs use defineConfig (e.g. packages/json-render-ui/vitest.config.ts) and import the Vue plugin as vue (lowercase). Using defineProject/Vue here is inconsistent and makes configs harder to scan across packages.
  • Files reviewed: 7/8 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@dvcolomban
dvcolomban marked this pull request as draft September 10, 2026 17:29
@dvcolomban
dvcolomban force-pushed the dvcol/fix-icon-retries branch from 00bd653 to 9e058e4 Compare September 10, 2026 18:00
@vercel

vercel Bot commented Sep 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
devframe Skipped Skipped Sep 10, 2026 7:57pm UTC

@dvcolomban
dvcolomban force-pushed the dvcol/fix-icon-retries branch from 9e058e4 to 1f99511 Compare September 10, 2026 18:11
@dvcolomban dvcolomban changed the title fix(hub-ui): retry transient icon requests fix(hub-ui): show failed icons and retry on remount Sep 10, 2026
@dvcolomban
dvcolomban marked this pull request as ready for review September 10, 2026 19:18
Copilot AI review requested due to automatic review settings September 10, 2026 19:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The changes correctly prevent caching invalid Iconify results, add a reliable fallback + retry-on-remount behavior, and are backed by targeted browser tests for the new failure modes.

Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@dvcolomban
dvcolomban force-pushed the dvcol/fix-icon-retries branch from 1f99511 to 7a2aab6 Compare September 10, 2026 19:34
Copilot AI review requested due to automatic review settings September 10, 2026 19:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The changes directly address the caching failure mode described, and the remaining feedback is limited to minor naming/accessibility improvements rather than correctness issues.

Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment thread packages/hub-ui/src/client/components/icons/IconifyIcon.vue
Comment thread packages/hub-ui/src/client/utils/iconify.ts Outdated
Copilot AI review requested due to automatic review settings September 10, 2026 19:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The URL/data <img> fallback in IconifyIcon.vue still lacks decorative semantics (alt="" + aria-hidden="true"), making accessibility behavior inconsistent across icon sources.

Review details

Suppressed comments (1)

packages/hub-ui/src/client/components/icons/IconifyIcon.vue:59

  • The URL/data img branch isn’t marked decorative: it has no alt and no aria-hidden, while the Iconify/failure SVG branches are aria-hidden. In dock buttons that already have an aria-label, this can cause screen readers to announce a stray “image” depending on icon source. Add alt="" and aria-hidden="true" to keep accessibility semantics consistent.
  <img
    v-else :src="icon"
    class="w-full h-full m-auto"
    draggable="false"
  >
  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI review requested due to automatic review settings September 10, 2026 19:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The changes are localized, align with the stated failure mode, and the updated logic prevents caching invalid SVG while safely degrading the UI on fetch failures.

Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI review requested due to automatic review settings September 10, 2026 19:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The changes are localized and consistent with the stated fix, with only minor non-blocking diagnostics/message improvements noted.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

packages/hub-ui/src/client/utils/iconify.ts:30

  • The thrown error for non-2xx responses omits which icon failed (collection/icon), which makes debugging production reports harder (especially when multiple icons are loading concurrently). Include the icon id (and optionally statusText/URL) in the message.

This issue also appears on line 35 of the same file.

packages/hub-ui/src/client/utils/iconify.ts:37

  • The generic "invalid SVG" error doesn’t include which icon triggered it, which makes it difficult to diagnose when this happens in the wild (e.g. CDN returning an HTML error page with 200). Include the icon id in the error message.
  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI review requested due to automatic review settings September 10, 2026 19:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The changes are small, locally contained, and correctly address the failure-caching and UI fallback behavior described in the PR.

Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

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