Skip to content

frontend: plugins: Show error notification when plugin loading fails - #6351

Merged
illume merged 2 commits into
kubernetes-sigs:mainfrom
krsatyamthakur-droid:frontend/plugin-load-error-notification-v2
Jul 13, 2026
Merged

illume merged 2 commits into
kubernetes-sigs:mainfrom
krsatyamthakur-droid:frontend/plugin-load-error-notification-v2

Conversation

@krsatyamthakur-droid

Copy link
Copy Markdown
Contributor

Previously, if fetchAndExecutePlugins() rejected (e.g. the backend was
unreachable), the error was silently swallowed by a bare .catch(console.error).
Users had no indication that plugins failed to load.

Replace it with a handler that logs the error and displays an error
snackbar via enqueueSnackbar(), matching the pattern used elsewhere in
the codebase for user-visible fetch failures.

Summary

When plugin loading fails, users now see an error snackbar instead of
nothing. The fix replaces the bare .catch(console.error) with a handler
that both logs and surfaces the error to the user.

Related Issue

Fixes #6349

Changes

  • frontend/src/plugin/Plugins.tsx: replaced .catch(console.error) with
    a handler that logs the error and calls enqueueSnackbar() with variant: 'error'
  • Updated all 17 locale files with the new translation string via npm run i18n

Steps to Test

  1. In frontend/src/plugin/index.ts, temporarily make fetchAndExecutePlugins
    throw (e.g. add throw new Error('test') at the top of the function)
  2. Run Headlamp and wait for it to load
  3. An error snackbar should appear saying "Failed to load plugins. Please try reloading the app."
  4. Remove the test throw and confirm normal plugin loading still works

Screenshots (if applicable)

N/A — the change is a snackbar that only appears on failure

Notes for the Reviewer

  • The new string follows the translation| namespace prefix convention
    already used in Plugins.tsx for the incompatible plugins warning
  • All locale files were regenerated with npm run i18n; non-English
    entries are placeholder strings that translation contributors can fill in

@kubernetes-prow kubernetes-prow Bot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Jul 3, 2026
@kubernetes-prow
kubernetes-prow Bot requested review from illume and sniok July 3, 2026 14:38
@kubernetes-prow kubernetes-prow Bot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Jul 3, 2026
@illume
illume requested a review from Copilot July 5, 2026 04:10

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.

Pull request overview

This PR makes plugin-load failures user-visible by replacing a silent .catch(console.error) in the frontend plugin loader with an error handler that logs the failure and shows an error snackbar. It also adds the corresponding i18n string across locales so the message is translatable (and can fall back to English where untranslated).

Changes:

  • Show an error snackbar when fetchAndExecutePlugins() rejects in frontend/src/plugin/Plugins.tsx.
  • Add the new “Failed to load plugins…” translation key across locale translation.json files.
  • Regenerate/sort locale glossary.json entries (e.g., moving “Logs: {{ itemName }}” to a different position).

Reviewed changes

Copilot reviewed 35 out of 35 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
frontend/src/plugin/Plugins.tsx Replace bare .catch(console.error) with an error handler that enqueues an error snackbar.
frontend/src/i18n/locales/ar/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/ar/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/bn/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/bn/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/de/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/de/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/en/translation.json Add the new plugin-load-failure translation key (English source string).
frontend/src/i18n/locales/en/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/es/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/es/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/fr/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/fr/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/he/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/he/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/hi/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/hi/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/it/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/it/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/ja/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/ja/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/ko/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/ko/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/pt/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/pt/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/ru/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/ru/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/ta/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/ta/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/ur/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/ur/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/zh/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/zh/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).
frontend/src/i18n/locales/zh-tw/translation.json Add the new plugin-load-failure translation key.
frontend/src/i18n/locales/zh-tw/glossary.json Regenerated glossary ordering/entries (includes moving “Logs: {{ itemName }}”).

Comment thread frontend/src/plugin/Plugins.tsx Outdated
@krsatyamthakur-droid

Copy link
Copy Markdown
Contributor Author

Good catch — I missed that index.ts does Promise.reject(resp) in a few places, so err isn't always an Error. Changed the type to unknown in the latest commit.

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.

Pull request overview

Copilot reviewed 35 out of 35 changed files in this pull request and generated 1 comment.

Comment thread frontend/src/plugin/Plugins.tsx Outdated

@illume illume 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.

Thanks for these changes.

Can you please address the open review comments? Once you've resolved each one, please mark it as resolved.

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.

Pull request overview

Copilot reviewed 35 out of 35 changed files in this pull request and generated 1 comment.

Comment thread frontend/src/plugin/Plugins.tsx Outdated
@kubernetes-prow kubernetes-prow Bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Jul 5, 2026

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.

Pull request overview

Copilot reviewed 35 out of 35 changed files in this pull request and generated 1 comment.

Comment thread frontend/src/plugin/Plugins.tsx
@krsatyamthakur-droid

Copy link
Copy Markdown
Contributor Author

Fixed. dispatch() was outside the try/catch so a throw there would go unhandled. Moved it inside and cleaned up the wrong comment too.

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.

Pull request overview

Copilot reviewed 35 out of 35 changed files in this pull request and generated no new comments.

@illume illume 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.

Thanks for this.

I wonder if you saw this error, or how you found it?

Could you please add a test case?

Comment thread frontend/src/plugin/Plugins.tsx
@krsatyamthakur-droid

Copy link
Copy Markdown
Contributor Author

While going through the plugin loading flow in index.ts, I noticed that when fetchAndExecutePlugins rejects — for example if the backend is down — the error just gets swallowed by .catch(console.error). Nothing shows up for the user. That felt like something worth fixing.

For the test, I added Plugins.test.tsx with two cases — one where the fetch fails and we verify the error snackbar actually shows up, and one where it succeeds and we check no error snackbar is triggered.

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.

Pull request overview

Copilot reviewed 36 out of 36 changed files in this pull request and generated no new comments.

@illume illume 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.

Thanks for these changes.

Can you please have a look at the git commits to see if they meet the contribution guidelines? We use a Linux kernel style of git commits. See the contributing guide for general context, and please see previous git commits with git log for examples.

Commits that need attention
  • frontend: plugins: add test for error snackbar and restore inline comment — Description must start with a capital letter — e.g. frontend: HomeButton: Fix the button not frontend: HomeButton: fix the button.
Commit guidelines
  • Use atomic commits focused on a single change.
  • Use the title format <area>: <Description of changes> — description must start with a capital letter.
  • Keep the title under 72 characters (soft requirement).
  • Explain the intention and why the change is needed.
  • Make commit titles meaningful and describe what changed.
  • Do not add code that a later commit rewrites; squash or reorder commits instead.
  • Do not include Fixes #NN in commit messages.

Good examples:

  • frontend: HomeButton: Fix so it navigates to home
  • backend: config: Add enable-dynamic-clusters flag

When fetchAndExecutePlugins() rejects (e.g. the backend is unreachable),
the error was silently swallowed by a bare .catch(console.error). Users
had no indication that plugin loading had failed.

Replace it with a handler that logs the error with context and shows an
error snackbar via enqueueSnackbar(), matching the pattern used elsewhere
in the codebase for user-visible fetch failures. The .catch() is placed
before .finally() so the error handler does not run on a clean load, and
the finally block is wrapped in try/catch so a dispatch failure cannot
escape silently.

Add the new translation string across all locale files.
Add Plugins.test.tsx with two cases: one that checks an error snackbar
is shown when fetchAndExecutePlugins rejects, and one that checks no
error snackbar fires on a successful load.
@krsatyamthakur-droid
krsatyamthakur-droid force-pushed the frontend/plugin-load-error-notification-v2 branch from 6a00a84 to e206252 Compare July 6, 2026 14:02
@krsatyamthakur-droid

Copy link
Copy Markdown
Contributor Author

Done — squashed all the fixup commits into two clean commits and removed the issue reference from the commit body.

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.

Pull request overview

Copilot reviewed 36 out of 36 changed files in this pull request and generated no new comments.

@kubernetes-prow kubernetes-prow Bot added needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. and removed needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. labels Jul 10, 2026

@illume illume 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.

🎉 thanks!

@kubernetes-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: illume, krsatyamthakur-droid

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubernetes-prow kubernetes-prow Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 13, 2026
@illume
illume merged commit 9582ae7 into kubernetes-sigs:main Jul 13, 2026
12 of 13 checks passed
@illume illume added this to the v0.44.0 milestone Jul 27, 2026
@illume illume added frontend Issues related to the frontend kind/bug Categorizes issue or PR as related to a bug. kind/feature Categorizes issue or PR as related to a new feature. plugins testing labels Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. frontend Issues related to the frontend kind/bug Categorizes issue or PR as related to a bug. kind/feature Categorizes issue or PR as related to a new feature. plugins size/L Denotes a PR that changes 100-499 lines, ignoring generated files. testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Plugins: plugin load failure is swallowed silently with no user-facing error

3 participants