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

# Errors

> The SDK error hierarchy and how to handle failures.

Every error thrown by the SDK extends `StructError`, so you can use `instanceof` checks to branch on failure mode without inspecting error messages.

```typescript theme={null}
import {
  StructError,
  HttpError,
  NetworkError,
  TimeoutError,
  WebSocketError,
  WebSocketClosedError,
} from "@structbuild/sdk";
```

## Hierarchy

```
StructError
├── HttpError
├── NetworkError
├── TimeoutError
└── WebSocketError
    └── WebSocketClosedError
```

| Error                  | Thrown when                                                                                            |
| ---------------------- | ------------------------------------------------------------------------------------------------------ |
| `HttpError`            | The server returned a non-2xx response. Exposes `status`, `statusText`, `body`, and `responseHeaders`. |
| `NetworkError`         | `fetch` failed before a response arrived (DNS failure, TLS error, connection refused, and so on).      |
| `TimeoutError`         | The request exceeded the configured `timeout` (default 30s) and was aborted.                           |
| `WebSocketError`       | A websocket operation failed (subscribe timeout, unexpected protocol message, listener threw).         |
| `WebSocketClosedError` | The websocket was closed unexpectedly. Exposes `code` and `reason`.                                    |

## REST

```typescript theme={null}
import { HttpError, TimeoutError, NetworkError } from "@structbuild/sdk";

try {
  const market = await client.markets.getMarket({ conditionId: "0x..." });
} catch (error) {
  if (error instanceof HttpError) {
    if (error.status === 404) {
      return null;
    }
    if (error.status === 429) {
      console.warn("Rate limited", error.responseHeaders?.get("retry-after"));
    }
    console.error(error.status, error.body);
  } else if (error instanceof TimeoutError) {
    console.error("Request timed out");
  } else if (error instanceof NetworkError) {
    console.error("Network error", error.cause);
  } else {
    throw error;
  }
}
```

### HttpError

```typescript theme={null}
class HttpError extends StructError {
  readonly status: number;
  readonly statusText: string;
  readonly body: unknown;
  readonly responseHeaders: Headers | undefined;
}
```

`body` is the parsed JSON response when the server returned JSON. Otherwise it is the raw response text.

## Retry integration

When `retry` is configured on the client, `HttpError` responses with retryable status codes (`429`, `500`, `502`, `503`, `504`), `NetworkError`, and `TimeoutError` are retried automatically before the error reaches your code. `Retry-After` headers are honoured. See [Configuration](/sdk/configuration).

## WebSocket

WebSocket errors are surfaced through the `error` event on the socket. For operations that return promises (`connect`, `subscribe`), rejected promises carry `WebSocketError` or `WebSocketClosedError`.

```typescript theme={null}
ws.on("error", (err) => {
  if (err instanceof WebSocketClosedError) {
    console.error("closed", err.code, err.reason);
  } else {
    console.error(err);
  }
});

try {
  await ws.subscribe("polymarket_trades", { condition_ids: ["0xabc..."] });
} catch (err) {
  if (err instanceof WebSocketError) {
    console.error("subscribe failed", err.message);
  }
}
```

## Listener errors

If an event listener throws, the SDK forwards the error to any `error` listeners and logs it to the console as a fallback. Listener exceptions never crash the socket.
