Skip to content

fix(Home): add AbortController cleanup to prevent memory leaks on unmount#7

Merged
alichherawalla merged 5 commits into
mainfrom
fix/abort-controller-cleanup
Feb 18, 2026
Merged

fix(Home): add AbortController cleanup to prevent memory leaks on unmount#7
alichherawalla merged 5 commits into
mainfrom
fix/abort-controller-cleanup

Conversation

@alichherawalla
Copy link
Copy Markdown
Contributor

Summary

  • Adds AbortController to useEffect in Home.tsx, passing signal to both fetch calls
  • Returns a cleanup function that calls controller.abort() on unmount
  • AbortError is silently swallowed in catch blocks — it is not a real fetch failure
  • Addresses Gemini high-priority review comment on PR fix: log fetch errors instead of silently swallowing them #6

Problem

The useEffect hook had no cleanup. If Home unmounted before either fetch completed (e.g. quick navigation away), React would attempt setMovies / setLoading on an unmounted component — causing a memory leak and "Can't perform a React state update on an unmounted component" warning.

Test plan

  • does not log console.error when fetch is aborted — new test asserts AbortError is silently ignored
  • All 24 existing tests still pass
  • pnpm --filter @stagepass/web test:coverage — 24/24 green

🤖 Generated with Claude Code

…ount

useEffect had no cleanup — if the component unmounted before fetches
completed, React would attempt state updates on an unmounted component.
AbortController cancels both fetches on cleanup. AbortError is silently
ignored (not treated as a fetch failure) per Gemini review on PR #6.
When a fetch is aborted (e.g. component unmount), the AbortError should
be swallowed — it is not a real failure. Verifies console.error is NOT
called when all fetches reject with an AbortError.
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @alichherawalla, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the Home component by addressing a potential memory leak issue. It ensures that ongoing data fetching operations are properly cancelled when the component unmounts, preventing React state updates on unmounted components and improving application stability. The change integrates AbortController into the useEffect hook, providing a robust cleanup mechanism for asynchronous operations.

Highlights

  • Memory Leak Prevention: Implemented AbortController within the useEffect hook in Home.tsx to prevent potential memory leaks when the component unmounts before fetch requests complete.
  • Fetch Request Abort Handling: The signal from AbortController is now passed to both movie and genre fetch calls, allowing them to be aborted.
  • Cleanup Function: A cleanup function has been added to useEffect that calls controller.abort() when the Home component unmounts.
  • Error Handling Refinement: Catch blocks for fetch requests now silently swallow AbortError instances, as these do not represent actual fetch failures but rather intentional cancellations.
  • New Test Case: A new test has been added to Home.test.tsx to specifically assert that console.error is not logged when a fetch request is aborted due to component unmount.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • packages/web/src/pages/Home.test.tsx
    • Added a new test case to verify that console.error is not logged when a fetch request is aborted due to component unmount.
  • packages/web/src/pages/Home.tsx
    • Introduced AbortController to manage fetch requests within the useEffect hook.
    • Passed the signal from AbortController to both /api/movies and /api/movies/meta/genres fetch calls.
    • Added a cleanup function to useEffect that calls controller.abort() to cancel pending fetch requests on component unmount.
    • Modified catch blocks for fetch requests to ignore AbortError instances, preventing unnecessary error logging.
Activity
  • The author, alichherawalla, addressed a high-priority review comment from Gemini on a previous pull request (fix: log fetch errors instead of silently swallowing them #6) regarding useEffect cleanup.
  • The author confirmed that a new test case was added to verify AbortError handling.
  • The author verified that all 24 existing tests still pass.
  • The author confirmed that test coverage (pnpm --filter @stagepass/web test:coverage) shows 24/24 green.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

coverage/ directories were untracked. Also removes accidental *copy.md
files that were left over from a previous session.
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly adds an AbortController to the useEffect hook in the Home component to cancel fetch requests on unmount, preventing potential memory leaks. The accompanying test effectively validates this new behavior. My review includes suggestions to improve the robustness of the fetch logic by adding checks for HTTP error responses, which is a critical part of handling data fetching.

Comment thread packages/web/src/pages/Home.tsx Outdated
const { signal } = controller;

fetch('/api/movies', { signal })
.then(res => res.json())
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

It's a good practice to check for HTTP error responses, as fetch only rejects on network errors, not on HTTP error statuses like 4xx or 5xx. Without this check, a non-OK response could lead to an attempt to parse a non-JSON body, causing a cryptic error.

      .then(res => {
        if (!res.ok) {
          throw new Error(`HTTP error! status: ${res.status}`);
        }
        return res.json();
      })

Comment thread packages/web/src/pages/Home.tsx Outdated

fetch('/api/movies/meta/genres')
fetch('/api/movies/meta/genres', { signal })
.then(res => res.json())
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

Similar to the movies fetch, it's important to handle HTTP error statuses here as well to make the data fetching more robust.

      .then(res => {
        if (!res.ok) {
          throw new Error(`HTTP error! status: ${res.status}`);
        }
        return res.json();
      })

fetch() only rejects on network errors — HTTP 4xx/5xx responses resolve
with a non-OK status. Without this check a 500 would try to parse an
error body as JSON and throw a cryptic error. Addresses high-priority
Gemini feedback on PR #7.
Adds two tests that verify a non-OK HTTP response (4xx/5xx) is treated
as an error and logged via console.error. Updates all existing mocks to
include ok: true to match the new res.ok guard.
@alichherawalla alichherawalla merged commit a564936 into main Feb 18, 2026
@alichherawalla alichherawalla deleted the fix/abort-controller-cleanup branch February 18, 2026 07:15
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.

1 participant