Skip to content

fix: resolved signal re-use on retry and storage null-set leak - #909

Open
saurabhhhcodes wants to merge 1 commit into
shouri123:mainfrom
saurabhhhcodes:fix/latemeet-batch-1
Open

fix: resolved signal re-use on retry and storage null-set leak#909
saurabhhhcodes wants to merge 1 commit into
shouri123:mainfrom
saurabhhhcodes:fix/latemeet-batch-1

Conversation

@saurabhhhcodes

@saurabhhhcodes saurabhhhcodes commented Jul 25, 2026

Copy link
Copy Markdown

Bug Fixes

1. fetchWithRetry reuses aborted AbortController signal on retries (src/utils/api.ts)

When a request is aborted (e.g. timeout via AbortController), fetchWithRetry passes the same options object — including the already-aborted signal — to each retry attempt. This causes all subsequent fetch calls to immediately reject with an AbortError, rendering the retry mechanism completely ineffective.
Fix: Destructure and omit signal from options on retry so each attempt gets a fresh signal-less request.

2. discardPendingMeetingSession and persistPendingMeetingSession leak storage (src/sessionStorage.ts)

Both functions use storage.set({ [PENDING_SESSION_KEY]: null }) which stores a null value in Chrome storage instead of removing the key. This leaves phantom null entries that waste storage quota and can interfere with state checks.
Fix: Use storage.remove(PENDING_SESSION_KEY) to properly clean up.

Summary by CodeRabbit

  • Bug Fixes
    • Improved popup stability when expected interface elements are unavailable.
    • Fixed API key visibility toggling when the input field is missing.
    • Pending meeting sessions are now properly removed after completion or dismissal.
    • Improved retry handling for interrupted network requests.

@github-actions

Copy link
Copy Markdown
Contributor

🚀 Thank You for Contributing to Late-Meet

Please ensure that:

  • the issue was assigned to you before opening this PR
  • the PR references the related issue
  • your changes follow repository contribution guidelines
  • the project builds successfully before submission

Unassigned, duplicate, or low-quality PRs may be closed.

Thank you for contributing 💙

@github-actions github-actions Bot added type:code Type: Code change gssoc Official GSSoC contribution issue gssoc:approved GSSoC: PR approved and scored bug Something isn't working size/S labels Jul 25, 2026
@github-actions

Copy link
Copy Markdown
Contributor

👋 Thank you @saurabhhhcodes for your contribution to Late-Meet!

⚠️ Warning: This PR does not seem to link to an open issue. Please edit the PR description to include Closes #XX to ensure your contribution counts for GSSoC points.

Please review any automated suggestions or code review comments that may appear below! We will review your PR as soon as possible!


Please consider starring the repository ⭐ to show your support!

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The changes harden popup DOM access, delete pending meeting sessions from Chrome storage, and exclude request abort signals from recursive fetch retries.

Changes

Popup defensive handling

Layer / File(s) Summary
Guard optional popup elements
src/popup.ts
Credential-based view switching and API-key visibility toggling now check that the relevant DOM elements exist before updating them.

Pending session cleanup

Layer / File(s) Summary
Remove pending session entries
src/sessionStorage.ts
Pending sessions are removed from Chrome storage after persistence or discard instead of being replaced with null.

Retry signal handling

Layer / File(s) Summary
Exclude signals from retries
src/utils/api.ts
Recursive fetchWithRetry calls omit the original request signal while preserving other retry options.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested labels: level:beginner

Suggested reviewers: shouri123, shouri123

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the two main fixes: retry signal reuse and removing null storage entries.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/popup.ts`:
- Around line 144-146: Update maybeStartPopupTour() to return immediately when
mainView is null before accessing mainView.style.display or starting the tour.
Keep the existing guarded setupView/mainView updates and only invoke the tour
logic when mainView exists.

In `@src/utils/api.ts`:
- Around line 49-50: Update the retry logic in fetchWithRetry so an active
options.signal is preserved for retries triggered by 429/5xx or transient
network errors, while an already-aborted signal is stripped. For the
aborted-signal retry path, create and pass a bounded fresh timeout signal so
validateOpenAIKey and validateElevenLabsKey remain time-limited.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 400f56dd-bc92-459f-b0db-34ac4dbf937b

📥 Commits

Reviewing files that changed from the base of the PR and between d216444 and f451cf7.

📒 Files selected for processing (3)
  • src/popup.ts
  • src/sessionStorage.ts
  • src/utils/api.ts

Comment thread src/popup.ts
Comment on lines +144 to 146
if (setupView) setupView.style.display = "none";
if (mainView) mainView.style.display = "block";
void maybeStartPopupTour();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Guard mainView inside maybeStartPopupTour() as well.

These guards still lead to maybeStartPopupTour(), which unconditionally evaluates mainView.style.display at Line 170. If mainView is missing, the save path still throws after the guarded updates. Return early when mainView is null before starting the tour.

Proposed fix
-    if (stored[POPUP_ONBOARDING_TOUR_KEY] || mainView.style.display === "none") return;
+    if (
+      stored[POPUP_ONBOARDING_TOUR_KEY] ||
+      !mainView ||
+      mainView.style.display === "none"
+    ) return;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/popup.ts` around lines 144 - 146, Update maybeStartPopupTour() to return
immediately when mainView is null before accessing mainView.style.display or
starting the tour. Keep the existing guarded setupView/mainView updates and only
invoke the tour logic when mainView exists.

Comment thread src/utils/api.ts
Comment on lines +49 to +50
const { signal: _signal, ...restOptions } = options;
return fetchWithRetry(url, restOptions, retries - 1, backoff * 2);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Preserve cancellation and timeouts for non-aborted retries.

This unconditionally removes options.signal, so retries triggered by 429/5xx or transient network errors no longer honor the caller’s active abort signal. In validateOpenAIKey and validateElevenLabsKey, the 5-second timeout therefore only bounds the first attempt; later retries can continue beyond it and may hang without any timeout. Strip the signal only when it is already aborted, and provide a bounded fresh timeout for that retry path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/utils/api.ts` around lines 49 - 50, Update the retry logic in
fetchWithRetry so an active options.signal is preserved for retries triggered by
429/5xx or transient network errors, while an already-aborted signal is
stripped. For the aborted-signal retry path, create and pass a bounded fresh
timeout signal so validateOpenAIKey and validateElevenLabsKey remain
time-limited.

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

Labels

bug Something isn't working gssoc:approved GSSoC: PR approved and scored gssoc Official GSSoC contribution issue needs-issue size/S type:code Type: Code change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant