> ## Documentation Index
> Fetch the complete documentation index at: https://docs.engini.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors & pagination

> The typed error hierarchy, status mapping, and how list methods paginate.

## Error hierarchy

Identical class names in both languages (`instanceof`-discriminable in TS):

```
EnginiError
├── EnginiNetworkError           transport failure before a response (DNS, connection, timeout)
├── EnginiAPIError               any non-2xx with a parseable body
│   ├── EnginiAuthError          401, 403
│   ├── EnginiNotFoundError      404
│   ├── EnginiValidationError    400, 422
│   ├── EnginiRateLimitError     429
│   ├── EnginiConflictError      409
│   └── EnginiServerError        5xx
├── EnginiClientError            SDK misuse (bad arguments, conflicting options)
├── EnginiConnectionError        no connection resolvable / no default set
├── EnginiToolsetError           unknown toolset id, ambiguous connection name
├── EnginiTimeoutError           a polled async job (refresh, OAuth) didn't finish in time
└── EnginiToolExecutionError     the tool ran but reported isSuccess == false
```

API errors expose the envelope's `errorCode` and `message`. `EnginiToolExecutionError` additionally carries `error_message`, `execution_info`, and `history_id` (`errorMessage`/`executionInfo`/`historyId` in TS).

<CodeGroup>
  ```python Python theme={null}
  from engini.errors import EnginiRateLimitError, EnginiToolExecutionError

  try:
      result = client.tools.execute("monday_create_item", {"name": "x"})
  except EnginiToolExecutionError as e:
      print("tool failed:", e.error_message, "history:", e.history_id)
  except EnginiRateLimitError:
      ...  # back off and retry
  ```

  ```typescript TypeScript theme={null}
  import { EnginiRateLimitError, EnginiToolExecutionError } from "@engini/sdk";

  try {
    const result = await client.tools.execute("monday_create_item", { name: "x" });
  } catch (e) {
    if (e instanceof EnginiToolExecutionError) console.error("tool failed:", e.errorMessage);
    else if (e instanceof EnginiRateLimitError) { /* back off and retry */ }
    else throw e;
  }
  ```
</CodeGroup>

<Warning>
  The SDKs do **not** retry automatically. If your workload can hit rate limits or transient 5xx, wrap calls with your own retry/backoff and honor `Retry-After` on 429s.
</Warning>

## Pagination

You don't page manually: every `list`-style method auto-paginates internally and returns the complete array (`tools.get`, `connections.list`, `connections.objects`, `applications.list`, `toolsets.list`). Use the REST API directly with `offset`/`top` if you need manual paging over very large sets - see [the pagination contract](/concepts/pagination-and-errors).
