Background
The MMV beta viewer (mmv.ui.beta) currently has no error handling. When any failure occurs — API error, missing file, network issue, image decode failure — the user sees an infinite progress spinner with no feedback or recovery option.
Both legacy viewers (desktop MMV and MobileFrontend ImageCarousel) handle errors:
MobileFrontend ImageCarousel (the mobile viewer we're directly replacing):
- On API failure OR image load failure, hides the spinner and shows a LoadErrorMessage with an error icon, message text (mobile-frontend-media-load-fail-message), and a "Refresh" retry link
- Retry re-triggers the router hashchange to recreate the overlay
- Disables detail toggling while error is displayed
- Single showLoadFailMsg() handler covers both failure modes
Legacy desktop MMV (mmv.js):
- Separates image loading and metadata fetching into independent promise chains with separate error handlers
- Image failure: shows error box in the canvas with retry + bug report links (canvas.showError())
- Metadata failure: still shows the image, degrades the metadata panel (panel.showError())
- Title-not-found (hash nav to absent image): closes viewer, shows mw.notify() with link to file page (onTitleNotFound())
- Progress bar explicitly hidden on any failure
MVP proposal
For feature parity with the MobileFrontend viewer, we need a single unified error state (we can adopt the legacy desktop viewer's more granular approach later if needed). User-facing error messages should use the new Codex Toast component (available in Codex 2.4.0, now in MW core), which provides toast notifications with built-in accessibility (role="alert"), swipe-to-dismiss on mobile, and auto-dismiss support.
Acceptance Criteria
Let's ensure the following scenarios are handled:
- Promise rejections in BetaViewer.loadImage() (would cover network failures, API responses like "file does not exist", thumbnail resolution failures, etc)
- @error handler on <img> in LightboxImage.vue (similar to what the MobileFrontend ImageCarousel does via $img.on('error', showLoadFailMsg))
- Add onTitleNotFound to BetaViewer.loadImageByTitle() (similar to what MMV desktop does)
In all cases, we probably want to close the viewer and show a Toast message with text like "Error loading image" – maybe with the specific image filename if we have it. We may be able to re-use an existing error message template (multimediaviewer-thumbnail-error might be good for general errors, and multimediaviewer-file-not-found-error would be good for title-not-found errors).
Files to modify
- extensions/MultimediaViewer/resources/mmv.ui.beta/BetaViewer.js — .catch() in loadImage(), onTitleNotFound() in loadImageByTitle()
- extensions/MultimediaViewer/resources/mmv.ui.beta/App.vue — mount CdxToastContainer
- extensions/MultimediaViewer/resources/mmv.ui.beta/LightboxImage.vue — @error handler on <img>, show toast






