fix(clerk-js): Add retry logic and race condition fixes for Cloudflar…#7766
fix(clerk-js): Add retry logic and race condition fixes for Cloudflar…#7766braden-clerk wants to merge 1 commit intomainfrom
Conversation
…e captcha error 200100
This fixes Cloudflare Turnstile error 200100 ("Widget not found") which occurs when the captcha container element isn't available during rendering.
Changes:
- Add '200' to shouldRetryTurnstileErrorCode to retry all 200xxx errors (including 200100)
- Add waitForElement() call before captcha.render() to verify container exists
- Update smart widget initialization to use waitForElement() instead of getElementById()
- Add test coverage for error codes 200, 200100, and 200xxx
These changes prevent race conditions where DOM elements are removed or not ready between checks and render calls, particularly during React/framework re-renders.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
📝 WalkthroughWalkthroughThe changes modify Turnstile CAPTCHA error handling and widget initialization logic. The retry mechanism is expanded to treat error codes starting with "200" as retriable, including code "200" itself. The widget initialization flow now includes element existence checks before proceeding: it waits for the CAPTCHA container element to exist when using a smart widget with a provided container, and re-verifies the widget container element exists before rendering. If the container element is not found, the token generation promise is rejected with an error. These changes affect the turnstile.ts implementation and corresponding test expectations. 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/clerk-js/src/utils/captcha/turnstile.ts (1)
151-219:⚠️ Potential issue | 🟠 MajorAsync Promise executor is an anti-pattern and flagged by static analysis.
The
asyncexecutor can lead to unhandled promise rejections if an error is thrown before the firstawait. Refactor to avoid the async executor pattern.Proposed fix
- const handleCaptchaTokenGeneration = async (): Promise<[string, string]> => { - return new Promise(async (resolve, reject) => { - try { - // Re-verify element exists right before render to prevent 200100 errors - const containerElement = await waitForElement(widgetContainerQuerySelector); - if (!containerElement) { - reject(['Widget container element not found', undefined]); - return; - } - - const id = captcha.render(widgetContainerQuerySelector, { + const handleCaptchaTokenGeneration = async (): Promise<[string, string]> => { + // Re-verify element exists right before render to prevent 200100 errors + const containerElement = await waitForElement(widgetContainerQuerySelector).catch(() => null); + if (!containerElement) { + throw ['Widget container element not found', undefined]; + } + + return new Promise((resolve, reject) => { + try { + const id = captcha.render(widgetContainerQuerySelector, {This moves the async operations outside the Promise executor, keeping only the synchronous callback-based
captcha.renderinside.
@clerk/agent-toolkit
@clerk/astro
@clerk/backend
@clerk/chrome-extension
@clerk/clerk-js
@clerk/dev-cli
@clerk/expo
@clerk/expo-passkeys
@clerk/express
@clerk/fastify
@clerk/localizations
@clerk/nextjs
@clerk/nuxt
@clerk/react
@clerk/react-router
@clerk/shared
@clerk/tanstack-react-start
@clerk/testing
@clerk/ui
@clerk/upgrade
@clerk/vue
commit: |
…e captcha error 200100
This fixes Cloudflare Turnstile error 200100 ("Widget not found") which occurs when the captcha container element isn't available during rendering.
Changes:
These changes prevent race conditions where DOM elements are removed or not ready between checks and render calls, particularly during React/framework re-renders.
Description
Checklist
pnpm testruns as expected.pnpm buildruns as expected.Type of change
Summary by CodeRabbit