# Error Handling for APIs

All API methods (`tokens.get`, `chains.get`, `pairs.get`, `quote.request`, `swap.build`, `swap.getSigning`, `swap.submitSigning`, `limit.*`, `status.getTransaction`, `health.get`) return Promises. On HTTP errors (4xx, 5xx) or when the API returns a body with an `error` property, the SDK throws a `RoutingEngineAPIError` instead of resolving.

### Error types

#### `RoutingEngineSDKError`

Base class for SDK errors. Use it when you want to catch any SDK-originated error.

* `message` (string): Error message.
* `cause` (unknown, optional): Original error or exception.

#### `ConfigTypeError`

Thrown in **development** when SDK config has invalid types (e.g. `timeout` not a number, `apiKey` not a string), or when unsupported options are used (e.g. `baseURL` — the SDK only calls Zert’s backend). In production, invalid values are logged and defaults are used instead. Extends `RoutingEngineSDKError`.

* `message` (string): Description of the invalid config.
* `field` (string, optional): Config key that failed validation.

#### `RoutingEngineAPIError`

Thrown when an API request fails (network error, HTTP error status, or API error payload). Extends `RoutingEngineSDKError`.

* `message` (string): Error message (from API when available).
* `statusCode` (number, optional): HTTP status code (e.g. 400, 401, 503).
* `body` (unknown, optional): Response body. When the API returns `{ error, meta }`, you can cast to `ApiErrorResponse` to read `error.code`, `error.message`, `error.details`, and `meta`.
* `cause` (unknown, optional): Underlying error (e.g. Axios error).

### API error response shape

When the server responds with an error payload, `body` matches `ApiErrorResponse`:

* `error.code` (string): Error code.
* `error.message` (string): Human-readable message.
* `error.details` (Record\<string, unknown>, optional): Additional details.
* `meta.requestId` (string): Request identifier.
* `meta.timestamp` (string): Timestamp.

### Handling errors

Check for `RoutingEngineAPIError` and use `statusCode` and `body` to handle specific cases (e.g. 401 Unauthorized, 400 Invalid request).

```typescript
import { RoutingEngineSDK, RoutingEngineAPIError, ApiErrorResponse } from 'routing-engine-sdk';

const sdk = new RoutingEngineSDK({
  api: { apiKey: 'your-api-key' },
});

try {
  const response = await sdk.quote.request({
    fromChain: 'arbitrum',
    toChain: 'avax',
    tokenIn: 'TBTC',
    tokenOut: 'WETH',
    network: 'mainnet',
    amount: '100.00',
    slippageBps: 75,
    recipient: '0x1234567890123456789012345678901234567890',
  });
  console.log(response);
} catch (e) {
  if (e instanceof RoutingEngineAPIError) {
    console.error('Status:', e.statusCode);
    console.error('Message:', e.message);
    if (e.body && typeof e.body === 'object' && 'error' in e.body) {
      const errBody = e.body as ApiErrorResponse;
      console.error('Code:', errBody.error.code);
      console.error('Details:', errBody.error.details);
      console.error('Request ID:', errBody.meta.requestId);
    }
  } else {
    throw e;
  }
}
```

### Global error callback

You can pass an `onError` callback when creating the SDK. It is invoked whenever an API error is about to be thrown.

```typescript
const sdk = new RoutingEngineSDK({
  api: {
    apiKey: 'your-api-key',
    onError: (error) => {
      if (error instanceof RoutingEngineAPIError && error.statusCode === 401) {
        // Handle unauthorized
      }
    },
  },
});
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.zert.com/routing-engine-sdk/error-handling-for-apis.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
