> ## Documentation Index
> Fetch the complete documentation index at: https://proclubs-sdk.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors and retries

> Handle stable SDK errors and understand transient request retries.

All stable SDK errors extend `ProClubsError` and expose a typed `code`.

| Error class | Code | Meaning |
| - | - | - |
| `ProClubsValidationError` | `VALIDATION` | Local input or client options are invalid |
| `ProClubsAbortError` | `ABORTED` | The caller or transport aborted the request |
| `ProClubsTimeoutError` | `TIMEOUT` | The final attempt ended in a timeout |
| `ProClubsNetworkError` | `NETWORK` | The final attempt ended in another transport failure |
| `ProClubsHttpError` | `HTTP` | EA returned a rejected HTTP response |
| `ProClubsResponseError` | `INVALID_RESPONSE` | A successful response had invalid JSON or an unexpected shape |

## Catch errors by class

```ts theme={null}
import {
  ProClubsClient,
  ProClubsError,
  ProClubsHttpError,
  ProClubsValidationError,
} from 'proclubs-sdk'

const proclubs = new ProClubsClient()

try {
  await proclubs.matches.list({ clubId: '12345', limit: 5 })
} catch (error) {
  if (error instanceof ProClubsValidationError) {
    console.error('Fix the request:', error.message)
  } else if (error instanceof ProClubsHttpError) {
    console.error({
      status: error.status,
      endpoint: error.endpoint,
      retryAfterMs: error.retryAfterMs,
      bodySnippet: error.bodySnippet,
    })
  } else if (error instanceof ProClubsError) {
    console.error(error.code, error.message)
  } else {
    throw error
  }
}
```

`ProClubsHttpError` adds the rejected `status`, internal `endpoint`, optional
`retryAfterMs`, and an optional sanitized body excerpt limited to 200 characters.
`ProClubsResponseError` adds the internal `endpoint`. Original errors are
available through `cause` where applicable.

## Retry policy

The SDK retries:

* network failures and timeouts;
* `429`, `502`, `503`, and `504` responses;
* `403` responses only when the body does not validate as the requested
  endpoint's expected payload, in the default HTTP mode.

Retries use exponential backoff from `baseDelayMs`. If EA returns `Retry-After`
with a longer delay, that value wins. The total number of attempts is bounded by
`maxAttempts`, from `1` through `5`.

<Info>
  EA has been observed returning valid payloads with status `403`. The SDK
  accepts such a response only when its body validates for that exact endpoint.
  A body such as `{ "error": "Forbidden" }` is never treated as valid data.
</Info>

## Stop on every 403

Set `httpMode: 'strict'` when a probe or consumer must stop on a 403 regardless
of its payload:

```ts theme={null}
import { ProClubsClient, ProClubsHttpError } from 'proclubs-sdk'

const proclubs = new ProClubsClient({ httpMode: 'strict' })

try {
  await proclubs.matches.list({ clubId: '12345' })
} catch (error) {
  if (error instanceof ProClubsHttpError && error.status === 403) {
    // Stop this probe or report that access was denied.
  } else {
    throw error
  }
}
```

Strict mode rejects a 403 on the first attempt with `ProClubsHttpError`, even
when `maxAttempts` is greater than `1`. The error includes `status: 403` and the
typed `endpoint`. The request emits `request:error` with code `HTTP` and status
`403`, without `request:success` or `request:retry` for that attempt. Other
statuses keep their existing retry behavior. Strict mode releases the response
without parsing its payload, so `bodySnippet` is unavailable for that error.
It does not change a value already served from the optional cache; use
`{ cache: 'bypass' }` when every call must reach the transport.

The SDK does not retry:

* local validation failures;
* caller aborts;
* a `2xx` response containing invalid JSON or an unexpected payload;
* non-retryable HTTP statuses.

<Tip>
  Avoid wrapping the client in an unbounded retry loop. If your application adds
  another retry layer, cap it and include the SDK's own `maxAttempts` in the
  total request budget.
</Tip>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.