From e625308881f129ba684a96fd082c92adc7499f2c Mon Sep 17 00:00:00 2001 From: Benny Joo Date: Tue, 27 Jan 2026 15:47:11 +0900 Subject: [PATCH] fix: Improve the error handling in Stripe collectCard method (#27249) * fix: improve error handling in Stripe collectCard method - Add CollectCardFailure error code for better error categorization - Replace generic error with ErrorWithCode for consistent error handling - Add error mappings for common Stripe errors (customer not found, invalid API key, rate limit, etc.) - Include Stripe error message when available for better debugging - Follow the same pattern used in chargeCard method Co-Authored-By: benny@cal.com * fix: add CollectCardFailure to getHttpStatusCode mapping This ensures the error returns 400 instead of 500 when collectCard fails. Co-Authored-By: benny@cal.com * docs: add comments explaining ChargeCardFailure vs CollectCardFailure Co-Authored-By: benny@cal.com * refactor: simplify collectCard error handling Remove complex error mapping logic per code review feedback. Co-Authored-By: benny@cal.com * test: add CollectCardFailure to HTTP status code tests Co-Authored-By: benny@cal.com --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- packages/app-store/stripepayment/lib/PaymentService.ts | 3 ++- packages/lib/errorCodes.ts | 3 +++ packages/lib/server/getServerErrorFromUnknown.test.ts | 1 + packages/lib/server/getServerErrorFromUnknown.ts | 1 + 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/app-store/stripepayment/lib/PaymentService.ts b/packages/app-store/stripepayment/lib/PaymentService.ts index 74e8927152..ec71326462 100644 --- a/packages/app-store/stripepayment/lib/PaymentService.ts +++ b/packages/app-store/stripepayment/lib/PaymentService.ts @@ -219,7 +219,8 @@ class StripePaymentService implements IAbstractPaymentService { bookingId, safeStringify(error) ); - throw new Error("Stripe: Payment method could not be collected"); + + throw new ErrorWithCode(ErrorCode.CollectCardFailure, "Stripe: Payment method could not be collected"); } } diff --git a/packages/lib/errorCodes.ts b/packages/lib/errorCodes.ts index d6f44ec92e..74a72ab3e9 100644 --- a/packages/lib/errorCodes.ts +++ b/packages/lib/errorCodes.ts @@ -9,7 +9,10 @@ export enum ErrorCode { // Domain-specific error codes PaymentCreationFailure = "payment_not_created_error", NoAvailableUsersFound = "no_available_users_found_error", + // Thrown when charging a card fails (e.g., insufficient funds, card declined during actual payment) ChargeCardFailure = "couldnt_charge_card_error", + // Thrown when collecting/verifying a payment method fails (e.g., card setup failed during HOLD payment flow) + CollectCardFailure = "couldnt_collect_card_error", RequestBodyWithouEnd = "request_body_end_time_internal_error", AlreadySignedUpForBooking = "already_signed_up_for_this_booking_error", FixedHostsUnavailableForBooking = "fixed_hosts_unavailable_for_booking", diff --git a/packages/lib/server/getServerErrorFromUnknown.test.ts b/packages/lib/server/getServerErrorFromUnknown.test.ts index 246ea2bcb7..f18b5181a1 100644 --- a/packages/lib/server/getServerErrorFromUnknown.test.ts +++ b/packages/lib/server/getServerErrorFromUnknown.test.ts @@ -20,6 +20,7 @@ const test400Codes = [ ErrorCode.BookerLimitExceeded, ErrorCode.BookerLimitExceededReschedule, ErrorCode.ChargeCardFailure, + ErrorCode.CollectCardFailure, ]; const test404Codes = [ diff --git a/packages/lib/server/getServerErrorFromUnknown.ts b/packages/lib/server/getServerErrorFromUnknown.ts index 8009f23a7d..723d9d5836 100644 --- a/packages/lib/server/getServerErrorFromUnknown.ts +++ b/packages/lib/server/getServerErrorFromUnknown.ts @@ -151,6 +151,7 @@ export function getHttpStatusCode(cause: Error | ErrorWithCode): number { case ErrorCode.EventTypeNoHosts: case ErrorCode.RequestBodyInvalid: case ErrorCode.ChargeCardFailure: + case ErrorCode.CollectCardFailure: return 400; // 409 Conflict case ErrorCode.NoAvailableUsersFound: