Skip to content

fix: prevent unhandled rejection when ref.current becomes null between async iterations#203

Open
jhotadhari wants to merge 1 commit into
SteffeyDev:masterfrom
jhotadhari:master
Open

fix: prevent unhandled rejection when ref.current becomes null between async iterations#203
jhotadhari wants to merge 1 commit into
SteffeyDev:masterfrom
jhotadhari:master

Conversation

@jhotadhari

Copy link
Copy Markdown

Problem

calculateRectFromRef has a while loop guard that waits for fromRef.current to become truthy, but the subsequent do...while loop calls getRectForRef(fromRef) on each iteration without re-checking. When the ref becomes null between async iterations (component unmount, rapid open/close, re-render), getRectForRef rejects with Error: getRectForRef - current is not set. This rejection is never caught, resulting in an unhandled promise rejection.

Fixes #153

Changes

1. AdaptivePopover.tsx — add null-guard in do-while loop

Mirrors the existing while loop pattern — if the ref is lost between async iterations, bail gracefully:

// Guard against ref becoming null between async iterations
if (!fromRef?.current) {
    this.debug('calculateRectFromRef - ref not set, bailing');
    return;
}

2. Utility.ts — resolve instead of reject

Changed getRectForRef to resolve with Rect(0, 0, 0, 0) instead of rejecting. This acts as a safety net for all callers (BasePopover, JSModalPopover, etc.) that use .then() without error handlers. The primary fix is #1 above; this is a belt-and-suspenders backup.

Verification

  • The existing while loop in calculateRectFromRef already uses the same guard pattern — this fix extends it to the do...while loop where it was missing
  • calculateRectFromRef already handles all-undefined rect properties (line 240-243), so the function is designed to tolerate missing measurements — the reject was preventing that graceful path from being reachable

🤖 Generated with Claude Code

calculateRectFromRef has a while-loop guard that waits for the ref
to become available, but the subsequent do-while loop calls
getRectForRef on each iteration without re-checking. When the ref
becomes null between async iterations (component unmount, re-render),
getRectForRef rejects, causing an unhandled promise rejection.

Two changes:
- AdaptivePopover: add null-guard in do-while loop (mirrors while-loop
  pattern) so the loop bails if ref is lost between iterations
- Utility: resolve with Rect(0,0,0,0) instead of rejecting, as a
  safety net for all callers of getRectForRef

Closes SteffeyDev#153

Co-Authored-By: Claude <noreply@anthropic.com>
@AdamGerthel

AdamGerthel commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

It seems to me like it kinda makes sense for getRectForRef to throw an error if the reference isn't there, so perhaps the guard is the most proper fix. Having getRectForRef return a Rect with incorrect values doesn't make much sense to me. It seems misleading. Another option is for getRectForRef to return undefined when there's no reference, and bail in the hook if rect is undefined.

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.

Error: getRectForRef - current is not set (Unhandled Promise Rejection) iOS

2 participants