Skip to content

fix: catch transient getRun failures in postgres waitFor poll - #149

Closed
SomSamantray wants to merge 1 commit into
yc-software:mainfrom
SomSamantray:fix/waitfor-unhandled-rejection
Closed

fix: catch transient getRun failures in postgres waitFor poll#149
SomSamantray wants to merge 1 commit into
yc-software:mainfrom
SomSamantray:fix/waitfor-unhandled-rejection

Conversation

@SomSamantray

@SomSamantray SomSamantray commented Aug 3, 2026

Copy link
Copy Markdown

Issue

waitFor's polling loop in postgres-run-store.ts called getRun(runId).then(...) with no .catch(). A transient query failure (e.g. a brief Postgres blip) became an unhandled rejection outside the returned promise, which can crash the process instead of letting waitFor time out normally. finish() also only cleared the poll interval, leaving the timeout timer pending.

Fix

  • Poll tick now catches a rejected getRun call, logs it, and lets the next tick (or the existing timeout) handle it — no behavior change on the success path.
  • finish() clears both the poll interval and the timeout timer.
  • Added a test that forces a rejection mid-poll and asserts no unhandled rejection occurs and waitFor still settles via its timeout.

Fixes #57


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

waitFor's setInterval poll called getRun(runId).then(...) with no
.catch(). A transient query failure (e.g. brief Postgres unavailability)
became an unhandled rejection outside the returned promise instead of
letting waitFor's own timeout report it normally. finish() also only
cleared the poll interval, leaving the timeout timer pending.

Fixes yc-software#57

@rajpratham1 rajpratham1 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.

This PR fixes a reliability issue in waitFor() by handling transient failures from the polling getRun() call instead of allowing them to surface as unhandled promise rejections. The change is small, targeted, and backed by an appropriate regression test.

What the change does
✅ Wraps the polling getRun(runId) promise chain with a .catch(...).
✅ Treats polling failures as transient instead of crashing the polling loop.
✅ Continues polling until either:
the run reaches a terminal state, or
the existing timeout expires.
✅ Logs the transient polling error to aid diagnosis.
✅ Adds a regression test that:
intentionally closes the PostgreSQL connection pool during polling,
verifies no unhandledRejection event is emitted,
confirms waitFor() still resolves through its normal timeout behavior.
Review

Strengths

✅ Fixes a real asynchronous error-handling gap.
✅ Preserves existing waitFor() semantics rather than changing observable behavior.
✅ The regression test accurately reproduces the failure scenario by forcing getRun() to reject mid-poll.
✅ Prevents noisy unhandled promise rejections that could otherwise terminate Node.js processes depending on runtime configuration.
Minor suggestion (non-blocking)

The current implementation logs every transient polling failure via console.error. If the database remains unavailable for an extended period, this could generate a large number of identical log entries (every 250 ms). Consider rate-limiting or deduplicating these messages, or using the project's structured logging facility if one exists. This would improve operational visibility without changing the recovery behavior.

@16francej 16francej added code-pr Code submitted instead of an ADR bug Something isn't working labels Aug 4, 2026
@ReganBell

Copy link
Copy Markdown
Collaborator

Fixed on our side, going out shortly with you as co-author on the commit 🙏

@ReganBell ReganBell closed this Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working code-pr Code submitted instead of an ADR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Handle PostgreSQL poll failures in run waitFor

4 participants