Skip to content

fix: lazy feed loader remains on Loading... after request failure - #1301

Open
Alexia-Soare wants to merge 4 commits into
developmentfrom
fix/lazy-feed-loader
Open

fix: lazy feed loader remains on Loading... after request failure#1301
Alexia-Soare wants to merge 4 commits into
developmentfrom
fix/lazy-feed-loader

Conversation

@Alexia-Soare

Copy link
Copy Markdown
Contributor

A [feedzy-rss] shortcode with lazy='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 a success:true payload missing data.content falls back to the error message.

  • Error message (feedzy-rss-feeds-admin-abstract.php) — the message is translatable and filterable via a new feedzy_lazyload_error_msg filter, mirroring the existing feedzy_lazyload_loading_msg filter 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 3
Loading

QA

  1. In WP Admin → Posts → Add New Post, insert a Shortcode block (the generic core block, not the Feedzy block — the Feedzy block intentionally skips lazy loading) containing:
    [feedzy-rss feeds='https://s3.amazonaws.com/verti-utils/sample-feed.xml' max='3' lazy='yes']
    
    Publish and view the post.
    Expect: "Loading..." appears briefly, then the feed items render.
  2. Edit the post and change max to 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 by lazy, reload once, right-click the lazy/ fetch request (not the feedzy-lazy.js script) → Block request URL. Change max again, 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.
  3. Remove the blocking pattern and reload the post with one more fresh max value.
    Expect: the feed loads normally again.

🤖 Generated with Claude Code

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>
@Alexia-Soare Alexia-Soare added the pr-checklist-skip Allow this Pull Request to skip checklist. label Jul 30, 2026
@pirate-bot pirate-bot added the pr-checklist-complete The Pull Request checklist is complete. (automatic label) label Jul 30, 2026
@pirate-bot

pirate-bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Plugin build for aeeddf3 is ready 🛎️!

Note

You can preview the changes in the Playground

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 after goto() and a Loading assertion, 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 thread tests/e2e/specs/import.spec.js Outdated
Comment on lines +128 to +130
await expect(lazyContainer).not.toContainText('Loading', {
timeout: 10000,
});
Comment thread tests/e2e/specs/import.spec.js Outdated
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>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@selul

selul commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

@Alexia-Soare lets reuse the strings here #1301 (comment)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Alexia-Soare

Copy link
Copy Markdown
Contributor Author

@Alexia-Soare lets reuse the strings here #1301 (comment)

Done

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

Labels

pr-checklist-complete The Pull Request checklist is complete. (automatic label) pr-checklist-skip Allow this Pull Request to skip checklist.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants