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

# Error Handling

> Handling errors from the Shopi Storefront SDK

## ShopiError

All SDK errors are instances of `ShopiError`. Use `instanceof` to catch them cleanly.

```typescript theme={null}
import { Shopi, ShopiError } from '@shopi-lk/storefront-sdk';

try {
  const product = await shop.products.getBySlug('missing-product');
} catch (error) {
  if (error instanceof ShopiError) {
    console.error(error.message); // human-readable message
    console.error(error.status);  // HTTP status code
    console.error(error.data);    // raw response body
  }
}
```

## Status codes

| Status | Meaning                              | What to do                             |
| ------ | ------------------------------------ | -------------------------------------- |
| `0`    | Network error — offline, DNS failure | Check connectivity, retry              |
| `401`  | Invalid or missing API key           | Check the key starts with `shopi_pk_`  |
| `403`  | Key does not have required scope     | Contact shop owner to regenerate key   |
| `404`  | Resource not found                   | Check slug or ID is correct            |
| `408`  | Request timed out                    | Increase `timeoutMs` or retry          |
| `429`  | Rate limit exceeded                  | Wait for `Retry-After` seconds         |
| `500`  | Server error                         | Retry with backoff                     |
| `502`  | Upstream unavailable                 | Retry — transient infrastructure issue |

## Automatic retries

The SDK automatically retries `500`, `502`, `503`, `504`, and `429` responses up to **2 times** with exponential backoff (300ms, then 600ms). You do not need to implement retry logic yourself.

For `429` responses, the SDK reads the `Retry-After` header and waits the correct amount of time before retrying.

## Timeout

Every request times out after **10 seconds** by default. A timed-out request throws `ShopiError` with `status: 408`.

```typescript theme={null}
// Increase timeout for slow connections
const shop = new Shopi({
  apiKey: process.env.SHOPI_API_KEY!,
  timeoutMs: 20000, // 20 seconds
});
```

## Full error handling example

```typescript theme={null}
import { Shopi, ShopiError } from '@shopi-lk/storefront-sdk';

const shop = new Shopi({ apiKey: process.env.SHOPI_API_KEY! });

async function getProduct(slug: string) {
  try {
    return await shop.products.getBySlug(slug);
  } catch (error) {
    if (error instanceof ShopiError) {
      switch (error.status) {
        case 404:
          return null; // product doesn't exist
        case 401:
          throw new Error('Invalid API key — check your configuration');
        case 429:
          throw new Error('Too many requests — slow down');
        case 0:
          throw new Error('No internet connection');
        default:
          throw new Error(`API error ${error.status}: ${error.message}`);
      }
    }
    throw error; // re-throw unexpected errors
  }
}
```
