fix: lazy feed loader remains on Loading... after request failure - #1301
Open
Alexia-Soare wants to merge 4 commits into
Open
fix: lazy feed loader remains on Loading... after request failure#1301Alexia-Soare wants to merge 4 commits into
Alexia-Soare wants to merge 4 commits into
Conversation
The lazy loader's AJAX call had no error callback, so any failed request (network failure, HTTP error, corrupted JSON) left the initial Loading... text visible indefinitely. The success handler also assumed a well-formed wp_send_json envelope and broke on raw string returns from the REST callback or responses without rendered content. Failed or malformed requests now replace the loading indicator with the server's message when one is present, or a localized error message filterable via feedzy_lazyload_error_msg. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
|
Plugin build for aeeddf3 is ready 🛎️!
Note You can preview the changes in the Playground |
There was a problem hiding this comment.
Pull request overview
Fixes lazy shortcode loaders remaining indefinitely in a loading state after failed or malformed requests.
Changes:
- Adds fallback handling for transport and malformed-response failures.
- Introduces a localized, filterable error message.
- Adds E2E coverage for lazy-load failure scenarios.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
js/feedzy-lazy.js |
Handles unsuccessful and unexpected AJAX responses. |
includes/abstract/feedzy-rss-feeds-admin-abstract.php |
Provides the localized lazy-load error message. |
tests/e2e/specs/import.spec.js |
Tests lazy-load response failure paths. |
Comments suppressed due to low confidence (2)
tests/e2e/specs/import.spec.js:165
- This starts waiting after navigation and after asserting the transient loading text. If the one-second timer fires before those operations finish, the request event is missed and this test times out despite correct behavior. Register the request promise before
goto()and avoid requiring the transient text to remain visible.
await expect(lazyContainer).toContainText('Loading');
await page.waitForRequest(/feedzy\/v\d+\/lazy/);
tests/e2e/specs/import.spec.js:190
- All four tests using this helper can race the loader:
waitForRequest()is registered aftergoto()and aLoadingassertion, while the request starts on a one-second timer. On a slow navigation the event and loading state can already be gone, producing flaky failures. Arm the request wait before navigation and then assert only the stable final state.
async function expectLazyResult(page, postId, expectedText) {
await page.goto(`/?p=${postId}`);
const lazyContainer = page.locator('.feedzy-lazy');
await expect(lazyContainer).toContainText('Loading');
await page.waitForRequest(/feedzy\/v\d+\/lazy/);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 'url' => get_rest_url( null, 'feedzy/v' . FEEDZY_REST_VERSION . '/lazy/' ), | ||
| 'rest_nonce' => wp_create_nonce( 'wp_rest' ), | ||
| 'nonce' => wp_create_nonce( 'feedzy' ), | ||
| 'error' => apply_filters( 'feedzy_lazyload_error_msg', __( 'The feed could not be loaded.', 'feedzy-rss-feeds' ), $feed_url ), |
Comment on lines
+128
to
+130
| await expect(lazyContainer).not.toContainText('Loading', { | ||
| timeout: 10000, | ||
| }); |
Comment on lines
+117
to
+124
| await page.goto(`/?p=${postId}`); | ||
|
|
||
| const lazyContainer = page.locator('.feedzy-lazy'); | ||
| await expect(lazyContainer).toBeVisible(); | ||
| await expect(lazyContainer).toContainText('Loading'); | ||
|
|
||
| // Wait until the lazy request has actually been attempted (and failed). | ||
| await page.waitForRequest(/feedzy\/v\d+\/lazy/); |
Render the filtered error message into each lazy block as a data attribute so feedzy_lazyload_error_msg works per feed URL instead of page-globally through the shared feedzy JS object. Make the failure tests deterministic: create the request listener before navigation, drop the racy loading-state assertions, and assert the rendered error message rather than the absence of the loader. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Soare-Robert-Daniel
approved these changes
Jul 30, 2026
Contributor
|
@Alexia-Soare lets reuse the strings here #1301 (comment) |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Contributor
Author
Done |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A
[feedzy-rss]shortcode withlazy='yes'left visitors on an indefinite "Loading..." whenever the request fetching the feed content failed — a dropped connection, an HTTP error, or a response the handler couldn't parse. The lazy loader now always exits the loading state: it renders the feed on success and shows an error message on any failure. Reported in issue #1299, originally from HelpScout conversation 3402495948.What changed
Lazy loader (
js/feedzy-lazy.js) — failed requests now replace "Loading..." with a localized "The feed could not be loaded." message. Before → after: stuck loader forever → error message about one second after the failure.Response handling — HTTP 200 responses without usable content no longer strand or blank the container:
wp_send_json_error()envelopes show the server's message, raw string returns from the REST callback are rendered as-is, and asuccess:truepayload missingdata.contentfalls back to the error message.Error message (
feedzy-rss-feeds-admin-abstract.php) — the message is translatable and filterable via a newfeedzy_lazyload_error_msgfilter, mirroring the existingfeedzy_lazyload_loading_msgfilter for the loading text.Lazy load flow
flowchart LR A[Page renders<br/>lazy shortcode] --> B{Cached<br/>content?} B -- Yes --> C[Feed shown<br/>immediately] B -- No --> D["Loading... +<br/>request to<br/>/feedzy/v1/lazy"] D --> E{Changed:<br/>response has<br/>rendered content?}:::changed E -- Yes --> F[Feed items shown] E -- "No, server sent<br/>a message" --> G[New:<br/>show server message]:::added E -- "No, request failed<br/>or malformed" --> H[New:<br/>show error message]:::added classDef added fill:#1a7f37,color:#fff,stroke:#116329,stroke-width:3px classDef changed fill:#9a6700,color:#fff,stroke:#5c3d00,stroke-width:3px,stroke-dasharray:6 3QA
Expect: "Loading..." appears briefly, then the feed items render.
maxto a value not used before (each successful load caches the rendered feed per attribute set, so a fresh value forces the loading state). Update the post. On the post's frontend page, open DevTools → Network, filter bylazy, reload once, right-click thelazy/fetch request (not thefeedzy-lazy.jsscript) → Block request URL. Changemaxagain, update, and reload the post.Expect: "Loading..." switches to "The feed could not be loaded." about one second after the blocked request appears — previously it stayed on "Loading..." indefinitely.
maxvalue.Expect: the feed loads normally again.
🤖 Generated with Claude Code