cimplify
TypeScript SDK

Errors

Every SDK method returns `Result<T, CimplifyError>`. Methods do not throw; instead you check `.ok` and branch on `error.code`. Wrap nothing in `try/catch`.

Result type

type Result<T, E = CimplifyError> =
  | { ok: true; value: T }
  | { ok: false; error: E }

CimplifyError

import { CimplifyError } from '@cimplify/sdk'

class CimplifyError {
  code: string                          // 'VALIDATION_ERROR', 'NOT_FOUND', 'RATE_LIMITED', ...
  message: string                       // human-readable
  retryable?: boolean                   // safe to retry?
  context?: Record<string, unknown>     // structured details (field name, validation rule, ...)
}

Read errors

const r = await client.catalogue.getProducts()

if (!r.ok) {
  console.error(r.error.code)        // machine-readable
  console.error(r.error.message)     // human-readable
  console.error(r.error.retryable)   // boolean
  console.error(r.error.context)     // optional structured detail
  return
}

console.log(r.value.items)

Branch on code

const r = await client.cart.addItem({ item_id: 'prod_xxx', quantity: 1 })

if (!r.ok) {
  switch (r.error.code) {
    case 'OUT_OF_STOCK':
      showToast('This item is out of stock')
      break
    case 'ITEM_UNAVAILABLE':
      showToast('No longer available')
      break
    case 'VALIDATION_ERROR':
      showToast(r.error.message)
      break
    case 'RATE_LIMITED':
      showToast('Slow down; try again in a moment')
      break
    default:
      showToast(r.error.message)
  }
}

Retry helper

Only retry when the server has marked the error retryable. Use exponential backoff and a small attempt cap.

import type { Result } from '@cimplify/sdk'

async function withRetry<T>(
  fn: () => Promise<Result<T>>,
  maxAttempts = 3,
): Promise<Result<T>> {
  let last!: Result<T>
  for (let i = 0; i < maxAttempts; i++) {
    last = await fn()
    if (last.ok) return last
    if (!last.error.retryable) return last
    await new Promise((resolve) => setTimeout(resolve, 250 * 2 ** i))
  }
  return last
}

const r = await withRetry(() => client.catalogue.getProducts({ limit: 24 }))

Common error codes

CodeRetryableMeaning
VALIDATION_ERRORNoBad input; fix the request
NOT_FOUNDNoResource missing or filtered out
UNAUTHORIZEDNoSign in / refresh the session
FORBIDDENNoAuthenticated but not allowed
RATE_LIMITEDYesBack off and retry
NETWORK_ERRORYesTransport failed before response
TIMEOUTYesServer did not respond in time
SERVER_ERRORYesGeneric 5xx

Checkout-specific codes

CodeRecoverableMeaning
INVALID_CARTNoCart is empty or no longer valid
ALREADY_PROCESSINGNoA checkout for this cart is already in flight
PAYMENT_FAILEDYesProvider declined; let the user retry
FX_QUOTE_FAILEDYesCould not lock an FX quote for the pay currency
AUTH_INCOMPLETEYesCustomer must finish OTP / PIN authorization
AUTH_LOSTYesSession expired mid-checkout
CHECKOUT_FAILEDSometimesGeneric terminal failure; read message + retryable

Schema-shape errors (testing only)

Inside the testing harness, assertX helpers throw SchemaViolationError with structured issues[]. This is the only place the SDK throws.

import { assertCart, SchemaViolationError } from '@cimplify/sdk/testing'

try {
  assertCart(response)
} catch (e) {
  if (e instanceof SchemaViolationError) {
    console.error(e.toJSON()) // RFC 7807 + structured issues[]
  }
}
  • Result<T, E> Why methods never throw, how to narrow

  • Idempotency Safe retries for write methods

  • Checkout Where most error codes show up

  • Auth UNAUTHORIZED + AUTH_LOST recovery

On this page