# Stripe SDK error handling that does not page you at 3am
Stripe errors are typed. Agents that match on message strings break the moment Stripe rewords a message. Catch the type, branch on the code, and get the retry policy right.
## stripe-node
Errors carry `err.type`, one of: `StripeCardError`, `StripeInvalidRequestError`, `StripeAPIError`, `StripeConnectionError`, `StripeAuthenticationError`, `StripeRateLimitError`, `StripePermissionError`, `StripeIdempotencyError`. Plus `err.code` (for example `card_declined`), `err.statusCode`, and `err.requestId` for support.
## stripe-python
Errors are exception classes under `stripe.error`: `CardError`, `RateLimitError`, `InvalidRequestError`, `AuthenticationError`, `APIConnectionError`, `PermissionError`, `IdempotencyError`, all subclassing `StripeError`. Attributes: `e.code`, `e.http_status`, `e.request_id`.
## The retry policy
- Retry with backoff: `StripeConnectionError` / `APIConnectionError`, `StripeAPIError`, `StripeRateLimitError` / `RateLimitError`. Always send the same Idempotency-Key on retry (separate skill).
- Surface to the user, do not retry: `StripeCardError` / `CardError` (the card was declined; retrying the same card is harassment), `StripeInvalidRequestError` / `InvalidRequestError` (your code is wrong), `StripeAuthenticationError` (your key is wrong).
- Never retry a declined card automatically. A decline is an answer, not a transient failure.
## Logging
Log `err.code` (or `e.code`), the type, and the request ID on every failure. When an operator asks Stripe support about a failed payment, the request ID is the first thing support asks for. Message strings are for humans; codes are for code.