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

# Handle errors from the Quickshops TypeScript SDK gracefully

> Learn how QuickshopsError works, what fields it exposes, and how to catch and respond to common HTTP error conditions in your storefront.

Every failed TypeScript SDK call throws a `QuickshopsError`. Because the SDK wraps all network communication, you get a consistent error shape regardless of whether the failure is an authentication problem, a rate limit, or a missing resource. Catching errors by type lets you respond precisely without parsing raw HTTP responses.

## The `QuickshopsError` class

`QuickshopsError` extends the native `Error` class and adds HTTP metadata:

| Field        | Type      | Description                                              |
| ------------ | --------- | -------------------------------------------------------- |
| `message`    | `string`  | Human-readable description of the error                  |
| `statusCode` | `number`  | HTTP status code returned by the API                     |
| `body`       | `string`  | Raw response body (often JSON with `code` and `message`) |
| `headers`    | `Headers` | Response headers, including `x-request-id` when present  |

Import `QuickshopsError` from `@quickshops/sdk/models/errors`. Import the client from `@quickshops/sdk` in server-only modules.

## Catching errors

Use `instanceof` to distinguish SDK errors from other thrown values.

```ts theme={null}
import { qs } from "@/lib/quickshops";
import { QuickshopsError } from "@quickshops/sdk/models/errors";

try {
  const { data: products } = await qs.products.productsGetAll();
} catch (err) {
  if (err instanceof QuickshopsError) {
    console.error(err.statusCode, err.message, err.body);
  }
}
```

## Common error codes

Parse `err.body` as JSON when you need machine-readable codes:

| Status | Typical code      | Cause                                                                                            |
| ------ | ----------------- | ------------------------------------------------------------------------------------------------ |
| `401`  | `UNAUTHORIZED`    | Your API key is missing, malformed, or has been revoked                                          |
| `403`  | `FORBIDDEN`       | The key is not allowed for this route, the request origin is blocked, or the store is not on Pro |
| `429`  | `RATE_LIMITED`    | Your requests have exceeded the allowed rate; back off and retry                                 |
| `404`  | `NOT_FOUND`       | The requested resource (product, cart, etc.) does not exist                                      |
| `409`  | `CONFLICT`        | A duplicate server-side request is already in progress                                           |
| `400`  | `INVALID_REQUEST` | The request payload is invalid                                                                   |

## Handling errors by status

You can branch on `err.statusCode` to respond differently to each condition.

```ts theme={null}
import { qs } from "@/lib/quickshops";
import { QuickshopsError } from "@quickshops/sdk/models/errors";

async function loadProducts() {
  try {
    const { data } = await qs.products.productsGetAll();
    return data;
  } catch (err) {
    if (err instanceof QuickshopsError) {
      if (err.statusCode === 401) {
        throw new Error("Store configuration error");
      }
      if (err.statusCode === 429) {
        throw new Error("Too many requests, please try again shortly");
      }
      if (err.statusCode === 404) {
        return null;
      }
    }
    throw err;
  }
}
```

<Tip>
  Include `err.headers.get("x-request-id")` in support requests. It uniquely identifies the failed API call on the server.
</Tip>
