Skip to content

feat(android): show why the editor document failed to load - #740

Merged
dcalhoun merged 5 commits into
trunkfrom
feat/android-surface-editor-load-errors
Sep 28, 2026
Merged

dcalhoun merged 5 commits into
trunkfrom
feat/android-surface-editor-load-errors

Conversation

@dcalhoun

@dcalhoun dcalhoun commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

What?

Surface helpful information when the editor fails to load, rather than displaying an infinite loading indicator.

Why?

When developing locally, forgetting a configuration step led to cryptic error messages in LogCat or the Chrome inspector.

How?

Track the URL used for editor loading. When using the local development server, surface details of the error and actionable steps to resolve it.

Testing Instructions

  1. On an emulator with GUTENBERG_EDITOR_URL=http://10.0.2.2:5173/ and no dev server running, open a post in the demo app. The error view appears with the "Is the dev server running?" hint instead of a spinner.
  2. Run make serve-dev and reopen the post. The editor loads.
  3. On a physical device, point GUTENBERG_EDITOR_URL at the host's LAN IP without a matching entry in network_security_config.xml. The error view shows the cleartext hint.
  4. On a physical device, set GUTENBERG_EDITOR_URL=http://10.0.2.2:5173/. After the connection times out, which can take a minute or two, the error view says 10.0.2.2 works only on the emulator and suggests the LAN IP address.
  5. On a physical device, set GUTENBERG_EDITOR_URL=http://localhost:5173/ with make serve-dev running and no port forwarding. The hint suggests adb reverse tcp:5173 tcp:5173. Run it and reopen the post. The editor loads.
  6. Remove GUTENBERG_EDITOR_URL, delete android/Gutenberg/src/main/assets/index.html, and rebuild the demo app. Opening a post shows the localized error view instead of a spinner. Restore the file with make copy-android-dist.
  7. With GUTENBERG_EDITOR_URL unset and the bundle restored, open a post containing media. The editor loads as before.

Accessibility Testing Instructions

N/A, no user-facing changes.

Screenshots or screencast

Screenshots

Error messages —
connection refused IP address clear text not permitted
connection timeout connection refused localhost
internet disconnected unknown error


AI-generated details

Problem

When the editor document failed to load (e.g. the dev server wasn't running, or a physical device lacked a cleartext entry for the host's IP), the editor showed an endless spinner. onReceivedError only logged the error object (Received web error: WV.cZ@6d44c24), and the globals injected into Chromium's error page raised a misleading localStorage SecurityError.

Mechanism

  • loadEditor records the URL it loads. When a main-frame request for that document fails, the existing error view replaces the spinner. This covers network failures (onReceivedError) and error statuses (onReceivedHttpError), including the asset loader's 404 for a missing bundled index.html.
  • With a dev server configured, the message names the URL and the error, plus a hint:
    • ERR_CONNECTION_REFUSED: start the dev server with make serve-dev. For localhost or 127.0.0.1, it also suggests adb reverse tcp:<port> tcp:<port>.
    • ERR_CLEARTEXT_NOT_PERMITTED: allow cleartext to the host in the network security config.
    • Timeouts, failed connections, and unresolvable or unreachable hosts: check the device can reach the host. For 10.0.2.2, it instead explains that the alias works only on the emulator and suggests the computer's LAN IP address.
    • An HTTP error status: check that GUTENBERG_EDITOR_URL points at the dev server.
  • The log line now includes the error code, description and URL.

Production path

  • Hints appear only when GUTENBERG_EDITOR_URL is set, which comes only from the gitignored local.properties. The bundled editor keeps the view's localized message, so no untranslated text reaches users.
  • Only a failure of the editor document triggers the error view. Failed subresources and other pages, such as a 404 image or REST request, are left alone.
  • The bundled document is served from the app, so it fails only when the build is broken. That case now shows the error view instead of a spinner.
  • Not covered: a server answering 200 with something other than the editor still leaves the spinner, since only a readiness timeout would catch it.

Testing

The Android library unit tests and make lint-android are green. On a device or emulator:

  1. With GUTENBERG_EDITOR_URL=http://10.0.2.2:5173/ and no dev server running, open a post in the demo app. The error view appears with the "Is the dev server running?" hint instead of a spinner.
  2. Run make serve-dev and reopen the post. The editor loads.
  3. On a physical device, point GUTENBERG_EDITOR_URL at the host's LAN IP without a matching entry in network_security_config.xml. The error view shows the cleartext hint.
  4. On a physical device, set GUTENBERG_EDITOR_URL=http://10.0.2.2:5173/. After the connection times out, which can take a minute or two, the error view says 10.0.2.2 works only on the emulator and suggests the LAN IP address.
  5. On a physical device, set GUTENBERG_EDITOR_URL=http://localhost:5173/ with make serve-dev running and no port forwarding. The hint suggests adb reverse tcp:5173 tcp:5173. Run it and reopen the post. The editor loads.
  6. Remove GUTENBERG_EDITOR_URL, delete android/Gutenberg/src/main/assets/index.html, and rebuild the demo app. Opening a post shows the localized error view instead of a spinner. Restore the file with make copy-android-dist.
  7. With GUTENBERG_EDITOR_URL unset and the bundle restored, open a post containing media. The editor loads as before.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CSbnGRWvgz7WNn6cGFRKxs

A failed load left an endless spinner and an opaque logcat line. The error view now appears, and a dev server failure names the likely cause: the server not running, a missing cleartext entry, or an unreachable host.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CSbnGRWvgz7WNn6cGFRKxs
@github-actions github-actions Bot added the [Type] Enhancement A suggestion for improvement. label Sep 28, 2026
@wpmobilebot

wpmobilebot commented Sep 28, 2026 •

Copy link
Copy Markdown

XCFramework Build

This PR's XCFramework is available for testing. Add the following to your Package.swift:

.package(url: "https://github.com/wordpress-mobile/GutenbergKit", branch: "pr-build/740")

Built from c2b7569

dcalhoun and others added 4 commits September 28, 2026 09:23
Timeouts, a disconnected device, and failed connections showed no hint, though they share the unreachable-host cause.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On a physical device, localhost is the device itself, so a refused connection usually means the port isn't forwarded rather than the server being stopped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… HTTP error

HTTP errors bypass onReceivedError, so a missing bundled index.html (a 404 from the asset loader) or a wrong dev server URL still left an endless spinner.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On a physical device, 10.0.2.2 times out rather than reaching the dev machine, and the generic reachability hint didn't name the cause.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dcalhoun
dcalhoun marked this pull request as ready for review September 28, 2026 14:05
@dcalhoun
dcalhoun requested a review from adalpari September 28, 2026 14:05

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

Tested and LGTM!

@dcalhoun
dcalhoun merged commit d2a92b7 into trunk Sep 28, 2026
32 checks passed
@dcalhoun
dcalhoun deleted the feat/android-surface-editor-load-errors branch September 28, 2026 15:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Android [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants