Page MenuHomePhabricator

Image Browsing: Add basic error handling for MMV Beta Viewer
Closed, ResolvedPublic3 Estimated Story Points

Description

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

Event Timeline

Sorry @egardner just getting to this today.

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.

This seems like a fine approach for our initial experiment. We can always improve later.

We may be able to re-use an existing error message template

Great idea. I would prefer to re-use existing error message templates to avoid re-writing and re-translating new strings.

SherryYang-WMF lowered the priority of this task from Medium to Low.May 19 2026, 5:46 PM

Change #1290009 had a related patch set uploaded (by LWatson; author: LWatson):

[mediawiki/extensions/MultimediaViewer@master] Image Browsing: error handling for beta viewer

https://gerrit.wikimedia.org/r/1290009

Given our goal is feature parity with the Mobile Frontend viewer, should we match their existing error display method, or is it okay to introduce the Codex Toast component?
Can you confirm where to display the error message? @JScherer-WMF

Legacy version:
The Mobile Frontend viewer displays the error message.

MobileFrontend_viewer_error.png (712×1,264 px, 48 KB)

Given our goal is feature parity with the Mobile Frontend viewer, should we match their existing error display method, or is it okay to introduce the Codex Toast component?
Can you confirm where to display the error message? @JScherer-WMF

Legacy version:
The Mobile Frontend viewer displays the error message.

MobileFrontend_viewer_error.png (712×1,264 px, 48 KB)

Great catch @lwatson. I'll mock something up for this right now.

Assuming this task is about the MediaViewer code project, hence adding that project tag so other people who don't know or don't care about team tags can also find this task when searching via projects or looking at workboards. Please set appropriate project tags when possible. Thanks.

egardner raised the priority of this task from Medium to High.Fri, Jun 12, 6:26 PM

Change #1302283 had a related patch set uploaded (by Eric Gardner; author: Eric Gardner):

[mediawiki/extensions/MultimediaViewer@master] ImageInfo: Add invalidate() to evict a single cached entry

https://gerrit.wikimedia.org/r/1302283

Change #1302283 merged by jenkins-bot:

[mediawiki/extensions/MultimediaViewer@master] ImageInfo: Add invalidate() to evict a single cached entry

https://gerrit.wikimedia.org/r/1302283

@JScherer-WMF Regarding the localized messages: the legacy mobile messages are stored in MobileFrontend (not MultimediaViewer), so I created new messages in MultimediaViewer to maintain parity. The downside is that this increases translators' workload and requires waiting for new translations to come in. An alternative is to reuse the existing translations from the legacy desktop messages in MultimediaViewer. Do you have a strong preference either way?

I. MobileFrontend - https://github.com/wikimedia/mediawiki-extensions-MobileFrontend/blob/master/i18n/en.json

"mobile-frontend-media-load-fail-message""There was an error while loading this image."
"mobile-frontend-media-load-fail-retry""Refresh"

II. MultimediaViewer - https://github.com/wikimedia/mediawiki-extensions-MultimediaViewer/blob/master/i18n/en.json

"multimediaviewer-thumbnail-error"."Sorry, the file cannot be displayed"
"multimediaviewer-thumbnail-error-retry""retry"

If you can use the old strings, that would be ideal.

Change #1290009 merged by jenkins-bot:

[mediawiki/extensions/MultimediaViewer@master] Image Browsing: error handling for BetaViewer

https://gerrit.wikimedia.org/r/1290009

Etonkovidova subscribed.
Testing Notes:

According to MVP proposal in task description:

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).

enwiki wmf.7Figma designenwiki wmf.8 (or enwiki beta)
Screenshot 2026-06-22 at 2.02.02 PM.png (2,206×1,108 px, 595 KB)
Screenshot 2026-06-22 at 2.35.05 PM.png (688×1,434 px, 41 KB)
Screenshot 2026-06-22 at 2.50.44 PM.png (648×823 px, 42 KB)
enwiki beta
Screenshot 2026-06-22 at 5.13.26 PM.png (680×1,442 px, 42 KB)
Screenshot 2026-06-22 at 5.23.34 PM.png (662×1,422 px, 58 KB)

Notes

  • I was not able to trigger other error messages, i.e.
"multimediaviewer-metadata-error": "Could not load image details (error: $1)",
"multimediaviewer-file-not-found-error": "Sorry, the file $1 cannot be displayed since it is not present on the current page.",
"multimediaviewer-thumbnail-error": "Sorry, the file cannot be displayed",
"multimediaviewer-thumbnail-error-description": "There seems to be a technical issue. You can $1 if it persists. Error: $2",
"multimediaviewer-thumbnail-error-retry": "retry",

@lwatson - please review the test results and let me know if more testing is needed.

Hey @Etonkovidova! My bad for not posting an update about the error messages. We ended up using these existing desktop error messages: multimediaviewer-file-not-found-error and multimediaviewer-thumbnail-error. We added a new message, "Refresh" (multimediaviewer-thumbnail-error-refresh-button), to MultimediaViewer.

Testing different error states:
I. Error loading the image

  • Test via distorting the image src in the dev tools Element panel.
  • Expected behavior: Displays a toast notification with an error message and "Refresh" button. Uses the Codex Toast to display the message. The viewer remains open, and the user can dismiss the error message. Swipe to dismiss the toast message on mobile or use the close button on a tablet/desktop device.

II. API failure

  • Test via blocking the URL in the dev tools Network panel.
  • Expected behavior: same as case I above

III. Image not found error

  • Test via navigating to a hash URL with a file title that is not present on the current page (e.g. #/media/File:DoesNotExist.jpg). Example: https://en.wikipedia.org/wiki/Cardinalidae#/media/File:DoesNotExist.jpg
  • Expected behavior: The viewer closes and a mw.notify() popup appears with the message "Sorry, the file [filename] cannot be displayed since it is not present on the current page" and a link to "Go to corresponding file page". The notification auto-dismisses after a few seconds.
  • Please verify if pressing the browser back button after the notification returns to the broken hash or skips it cleanly.

Screenshot 2026-06-22 at 9.07.21 PM.png (624×268 px, 68 KB)

Thank you, @lwatson - will do more testing today and post the test result summary.