fix: prevent duplicate Stripe customers from broad catch in createStripeCustomerId#29764
fix: prevent duplicate Stripe customers from broad catch in createStripeCustomerId#29764prathamesh04 wants to merge 1 commit into
Conversation
…ipeCustomerId The createStripeCustomerId function used a try/catch that treated all errors the same as 'no customer found'. When Stripe API errors occurred (auth failures, network issues, rate limits), the catch block silently created a new customer instead of propagating the error, resulting in duplicate Stripe customers. Replace the broad catch with an explicit check on the response data length — only create a new customer when the list is genuinely empty. Fixes calcom#29455 Signed-off-by: Prathamesh Hukkeri <prathamesh04@users.noreply.github.com>
|
Welcome to Cal.diy, @prathamesh04! Thanks for opening this pull request. A few things to keep in mind:
A maintainer will review your PR soon. Thanks for contributing! |
📝 WalkthroughWalkthroughUpdated 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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.
🧹 Nitpick comments (1)
apps/api/v2/src/modules/stripe/stripe.service.ts (1)
235-259: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low valuePotential TOCTOU race when creating Stripe customers.
Two concurrent requests for the same email could both observe an empty customer list and proceed to create duplicate customers. While this PR correctly fixes the broad-catch path to duplicates, the race window remains. Consider using a database-level unique constraint on
stripeCustomerIdmetadata or a distributed lock if duplicate prevention is a strict requirement.This is a pre-existing pattern shared with the downstream consumer in
packages/app-store/stripepayment/lib/customer.ts:33-67, so it may be out of scope here.🤖 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 `@apps/api/v2/src/modules/stripe/stripe.service.ts` around lines 235 - 259, The createStripeCustomerId flow still has a check-then-create race that can produce duplicate Stripe customers for the same email. If duplicate prevention is in scope, add synchronization around this flow using a database-enforced uniqueness mechanism for stripeCustomerId or an appropriate distributed lock, while preserving the existing lookup, creation, metadata update, and return behavior; otherwise leave this pre-existing pattern unchanged.
🤖 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.
Nitpick comments:
In `@apps/api/v2/src/modules/stripe/stripe.service.ts`:
- Around line 235-259: The createStripeCustomerId flow still has a
check-then-create race that can produce duplicate Stripe customers for the same
email. If duplicate prevention is in scope, add synchronization around this flow
using a database-enforced uniqueness mechanism for stripeCustomerId or an
appropriate distributed lock, while preserving the existing lookup, creation,
metadata update, and return behavior; otherwise leave this pre-existing pattern
unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: f06c3c72-5b0d-4c59-8a8a-2133e0ab3ba1
📒 Files selected for processing (1)
apps/api/v2/src/modules/stripe/stripe.service.ts
|
Hey @bandhan-majumder — this is a small fix for #29455 where the broad catch in |
Overview
The
createStripeCustomerIdfunction used a broad try/catch that treated all errors the same as 'no customer found'. When Stripe API errors occurred (auth failures, network issues, rate limits), the catch block silently created a new customer instead of propagating the error — resulting in duplicate Stripe customers for the same email.Fixes #29455
Changes
try/catchwith an explicit check oncustomersResponse.data.lengthTechnical Details
Before:
After:
The root cause was that
data[0]on an empty array returnsundefined, and accessing.idonundefinedthrows a TypeError. The catch block then treated this the same as any real Stripe error and created a new customer — causing duplicates.Test plan
createStripeCustomerIdcovering empty list, existing customer, and Stripe error cases