Error Handling
Every backend call throws a typed ChromeShipError. Branch on error.code instead of parsing strings.
Error codes
| Code | HTTP | What to do |
|---|---|---|
auth_required | — | No session at all. Thrown manually — never from HTTP status. Show login. |
auth_expired | 401 | Server returned 401 — token expired. Re-authenticate. |
entitlement_required | 402 | User needs to pay. Send to checkout. |
forbidden | 403 | Insufficient permissions. |
bad_request | 400 / 422 | Invalid input. Check the payload. |
rate_limited | 429 | Too many requests. Back off. |
server_error | 500+ | Server-side failure. Retry or contact support. |
network_error | — | Fetch failed. Check connection, retry. |
unknown | — | Unexpected. Report the error. |
Usage
import { ChromeShipError } from "@/integrations/shared";
try {
await billing.requireAccess("pro");
} catch (error) {
if (error instanceof ChromeShipError) {
switch (error.code) {
case "entitlement_required":
await billing.checkout({ mode: "payment", priceId: "price_xxx" });
break;
case "auth_expired":
// Show re-authentication UI
break;
case "network_error":
// Show offline state, allow retry
break;
}
}
}