Skip to content

fix(android): reset readiness when the editor crashes - #640

Draft
dcalhoun wants to merge 1 commit into
fix/reset-host-readiness-on-editor-crashfrom
fix/android-reset-readiness-on-editor-crash
Draft

fix(android): reset readiness when the editor crashes#640
dcalhoun wants to merge 1 commit into
fix/reset-host-readiness-on-editor-crashfrom
fix/android-reset-readiness-on-editor-crash

Conversation

@dcalhoun

@dcalhoun dcalhoun commented Sep 9, 2026

Copy link
Copy Markdown
Member

What?

Android never cleared isEditorLoaded, so every guard built on it kept passing after the editor crashed.

Why?

isEditorLoaded is set once in onEditorLoaded and cleared nowhere — not on an editor crash, and not even on WebView process termination, which iOS does handle in controllerWebContentProcessDidTerminate.

So after the editor's ErrorBoundary unmounts the editor and deletes the window.editor.* methods, calls still reach a web view that can no longer answer them. This is the Android half of CMM-2008; #638 covers iOS and adds the onEditorUnavailable message this receives.

It also unblocks the host: GutenbergKitEditorFragment.editorReady has the same never-reset problem, and its updateFromEditor guard cannot start working until GutenbergKit tells it the editor is gone.

How?

  • Receive onEditorUnavailable over the existing editorDelegate interface and clear isEditorLoaded.
  • Add EditorUnavailableListener plus setEditorDidBecomeUnavailable, mirroring the existing EditorAvailableListener pattern, and clear it alongside the other listeners on teardown.

Relationship to #639

#639 fixes the consequence — one call site that turned a failed read into an empty title, which WordPress-Android persisted locally and then sent to the server. This PR fixes the cause, so the call is not made at all. They are independent and worth having both: #639 protects any host on today's release without a host change, this one stops the whole class.

Both touch GutenbergView.kt but in different regions, so they should rebase cleanly in either order.

Not included

  • didFireEditorLoaded is deliberately untouched. It guards the available listener against firing twice, and changing it would alter reload behaviour that has no reload path yet.
  • Host-side work — resetting GutenbergKitEditorFragment.editorReady and disabling the controls that no longer function — is a separate WordPress-Android change.

Testing Instructions

Unit tests: ./android/gradlew -p ./android :Gutenberg:testDebugUnitTest --tests "org.wordpress.gutenberg.GutenbergViewTest"

Two tests cover this. Note the second asserts that no JavaScript reaches the web view rather than asserting on the callback — Robolectric's shadow WebView never invokes the ValueCallback, so a callback-based assertion passes with or without the fix. I verified the committed version fails when the reset is removed.

Manually, in the demo app:

  1. Open the editor and trip the boundary from chrome://inspect:
    const be = wp.data.select( 'core/block-editor' );
    be.getBlockOrder = () => { throw new Error( 'repro' ); };
    wp.data.dispatch( 'core/block-editor' ).updateSettings( {} );
  2. adb logcat | grep GutenbergView shows EditorUnavailable received in native code.
  3. Confirm normal editing, undo/redo and saving still work without a crash.

Accessibility Testing Instructions

N/A — no UI changes.

Screenshots or screencast

N/A

🤖 Generated with Claude Code

https://claude.ai/code/session_01VuxMbKtUsaUF8nUVgKdxwK

`isEditorLoaded` was set once and never cleared — not on an editor crash, and
not even on WebView process termination, which iOS does handle. Every guard
built on it therefore kept passing after the editor's `ErrorBoundary` unmounted
the editor and deleted the `window.editor.*` bridge methods.

Receive the `onEditorUnavailable` message the editor now emits, clear
readiness, and expose an `EditorUnavailableListener` so hosts can disable the
controls that depend on the editor while leaving saving and closing available.

This is a second line of defense behind #639, which stops the one call site
that turned a failed read into an empty title. Here the calls stop being made
at all.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VuxMbKtUsaUF8nUVgKdxwK
@github-actions github-actions Bot added the [Type] Bug An existing feature does not function as intended label Sep 9, 2026
@dcalhoun
dcalhoun added this pull request to stack #641 September 9, 2026 16:24
@wpmobilebot

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/640")

Built from 383662b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Type] Bug An existing feature does not function as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants