Skip to content

fix(frontend): preserve created feeds when preview loading fails#915

Merged
gildesmarais merged 2 commits intomainfrom
slice/reliable-feed-creation
Mar 28, 2026
Merged

fix(frontend): preserve created feeds when preview loading fails#915
gildesmarais merged 2 commits intomainfrom
slice/reliable-feed-creation

Conversation

@gildesmarais
Copy link
Copy Markdown
Member

Summary

  • preserve created feed result when preview loading fails
  • move preview hydration into conversion flow so creation success is not blocked by preview fetch
  • update UI state copy to match the new creation/preview lifecycle

Validation

@gildesmarais gildesmarais changed the title Reliable Feed Creation Flow fix(web): preserve created feeds when preview loading fails Mar 27, 2026
@gildesmarais gildesmarais changed the title fix(web): preserve created feeds when preview loading fails fix(frontend): preserve created feeds when preview loading fails Mar 27, 2026
@gildesmarais gildesmarais requested a review from Copilot March 27, 2026 23:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Updates the frontend feed-creation flow so a created feed result is retained even when the JSON Feed preview request fails, and adjusts UI/test expectations for the new result shape that includes preview state.

Changes:

  • Extend feed conversion result to include { feed, preview }, and move preview hydration into the conversion hook.
  • Update ResultDisplay/AppPanels UI to render preview state from conversion results and show an explicit “Preparing feed” loading notice.
  • Update unit/contract tests and test setup to reflect the new lifecycle and preview fetch behavior.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
frontend/src/hooks/useFeedConversion.ts Returns CreatedFeedResult and fetches/parses JSON Feed preview during conversion.
frontend/src/hooks/useApiMetadata.ts Switches from AbortController to a cancellation flag in the metadata loader effect.
frontend/src/components/ResultDisplay.tsx Consumes preview state from conversion result (removes its own preview fetch/parsing).
frontend/src/components/AppPanels.tsx Updates loading copy and adds a loading notice while converting.
frontend/src/api/contracts.ts Adds CreatedFeedResult and preview-related types.
frontend/src/tests/useFeedConversion.test.ts Updates expectations for { feed, preview } and adds preview-failure coverage.
frontend/src/tests/useFeedConversion.contract.test.ts Extends contract coverage to include preview fetch and preview-failure behavior.
frontend/src/tests/setup.ts Adjusts MSW server wiring and adds globalThis storage stubs.
frontend/src/tests/ResultDisplay.test.tsx Removes preview-fetch mocking; tests preview rendering via provided props.
frontend/src/tests/App.test.tsx Updates mocked conversion result shape and asserts new loading/preview messaging.
frontend/src/tests/App.contract.test.tsx Updates preview route to .json to match preview fetch behavior.
Gemfile Adds irb to the development gem group.


return {
items,
error: items.length > 0 ? null : 'Preview unavailable right now.',
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

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

loadPreview sets preview.error to "Preview unavailable right now." whenever the feed returns zero items (even with an OK response). An empty feed is a valid state, so this will incorrectly show an error message for legitimate empty previews. Set error to null when the request succeeds, and only set an error when the fetch/JSON parsing fails (or when the payload is malformed).

Suggested change
error: items.length > 0 ? null : 'Preview unavailable right now.',
error: null,

Copilot uses AI. Check for mistakes.
Comment on lines 22 to 31
useEffect(() => {
const controller = new AbortController();
let cancelled = false;

const load = async () => {
setState((prev) => ({ ...prev, isLoading: true, error: null }));

try {
const response = await fetch('/api/v1', {
signal: controller.signal,
headers: { Accept: 'application/json' },
});
Copy link

Copilot AI Mar 28, 2026

Choose a reason for hiding this comment

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

The effect cleanup now only flips a cancelled flag but does not abort the in-flight metadata fetch. This can leave unnecessary network work running after unmount (and can keep the connection open longer than needed). Consider restoring an AbortController and passing signal to fetch, while still guarding state updates with the cancelled flag if desired.

Copilot uses AI. Check for mistakes.
@gildesmarais gildesmarais merged commit 383ecc3 into main Mar 28, 2026
12 checks passed
@gildesmarais gildesmarais deleted the slice/reliable-feed-creation branch March 28, 2026 00:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants