Visitar URL original
fix(credential-provider-node): handle passive credential refresh rejection by JosephDoUrden · Pull Request #8281 · aws/aws-sdk-js-v3 · GitHub
Skip to content

fix(credential-provider-node): handle passive credential refresh rejection - #8281

Merged
smilkuri merged 1 commit into
aws:mainfrom
JosephDoUrden:fix/credential-provider-node-passive-refresh-rejection
Aug 31, 2026
Merged

smilkuri merged 1 commit into
aws:mainfrom
JosephDoUrden:fix/credential-provider-node-passive-refresh-rejection

Conversation

@JosephDoUrden

Copy link
Copy Markdown
Contributor

Issue

Fixes #8280

Description

The passive background refresh in memoizeChain is the only one of the three locks that is never awaited, and it had no rejection handler, so a transient failure of the background chain(options) call escaped as a process-level unhandledRejection that consumer code cannot catch. Trigger sequence and production details are in the linked issue.

The failure is safe to contain: the cached credentials returned on the passive path are still valid, and the .finally() from #7692 already releases the lock so the next invocation retries the chain. This adds a .catch() between the .then and the .finally, with a comment explaining why containment is correct there. No change to the success path or to the active and force-refresh locks.

Testing

Added "should not surface an unhandled rejection when the passive refresh fails" to memoize-chain.spec.ts. It listens for unhandledRejection, caches valid credentials, then triggers a passive refresh that rejects. It asserts the listener captures nothing while the caller keeps receiving the cached credentials, and that a later invocation retries the chain and picks up the refreshed set.

Checklist

  • If the PR is a feature, add integration tests (*.integ.spec.ts) or E2E tests.
    • It's not a feature.
  • My E2E tests are resilient to concurrent i/o.
    • I didn't write any E2E tests.
  • I added access level annotations e.g. @public, @internal tags and enabled doc generation on the package. Remember that access level annotations go below the description, not above.
    • I didn't add any public functions.
  • Streams - how do they work?? My WebStream readers/locks are properly lifecycled. Node.js stream backpressure is handled. Error handling.
    • No streams here.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Without the fix the new case fails (AssertionError: expected [ …(1) ] to deeply equal [], the captured entry being the CredentialsProviderError); suite: 1 failed | 22 passed. With the fix: 3 files, 23 tests, all passing.

Drafted with AI assistance; reviewed and tested by the author.

@JosephDoUrden
JosephDoUrden requested a review from a team as a code owner August 26, 2026 17:51
…ction

The passive background refresh in memoizeChain is fire-and-forget:
unlike the active and force-refresh locks, it is never awaited, so its
rejection cannot reach any caller. It also had no rejection handler,
which turned a transient failure of the background chain() call into a
process-level unhandledRejection that consumer code cannot catch. The
cached credentials returned on the passive path are still valid, and the
finally block already releases the lock so the next invocation retries,
making the rejection safe to contain.

The fire-and-forget passive lock dates to aws#7456. aws#7692 later added the
finally lock-release to both the active and passive locks but added no
catch to either; the awaited locks surface their rejections to the
caller, so only the passive branch needed one. Adds the missing
passive-rejection spec case, which fails without this change.
@smilkuri
smilkuri force-pushed the fix/credential-provider-node-passive-refresh-rejection branch from 92c9fc4 to b2fa082 Compare August 31, 2026 19:07
@smilkuri
smilkuri merged commit f36843d into aws:main Aug 31, 2026
2 of 3 checks passed
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.

Failed passive credential refresh in memoizeChain causes an unhandled promise rejection (credential-provider-node)

3 participants