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

# 錯誤處理

> 使用 TheoApiError 處理 API 錯誤。

## TheoApiError

所有 REST API 錯誤都會以帶有結構化詳情的 `TheoApiError` 實例拋出。

```typescript theme={null}
import { Theo, TheoApiError } from "@hitheo/sdk";

try {
  const res = await theo.complete({ prompt: "Hello" });
} catch (err) {
  if (err instanceof TheoApiError) {
    console.log(err.status);              // 401
    console.log(err.message);             // "Theo API error 401: Invalid API key"
    console.log(err.details?.code);       // "invalid_api_key"
    console.log(err.details?.type);       // "authentication_error"
    console.log(err.details?.request_id); // "req_9f2e1a" — share in support tickets
    console.log(err.url);                 // "https://www.hitheo.ai/api/v1/completions"
  }
}
```

## 錯誤屬性

| 屬性 | 類型 | 說明 |
| - | - | - |
| `status` | `number` | HTTP 狀態碼（網絡/超時/取消時為 `0`） |
| `kind` | `string` | `"http"` \| `"timeout"` \| `"cancelled"` \| `"network"` —— 應基於此字段分支處理，而不是做字符串匹配 |
| `message` | `string` | 可讀的錯誤信息 |
| `body` | `string` | 原始響應體 |
| `url` | `string` | 請求 URL |
| `details` | `object \| null` | 解析後的 `{ message, type, code, request_id }` |

## 錯誤類型

`TheoApiError` 是基類 —— 下面每種錯誤都是 `TheoApiError` 的實例，因此現有的 catch 代碼塊仍然可以正常工作。若需要精確處理，請基於子類（或 `err.kind`）分支：

* **`TheoTimeoutError`**（`kind: "timeout"`）—— SDK 在 `timeoutMs`（單次請求 / 流連接）或 `streamIdleTimeoutMs`（流空閒）超時後主動中止。相關超時預算保存在 `.timeoutMs` 中。**不會**在 POST 請求上自動重試。
* **`TheoCancelledError`**（`kind: "cancelled"`）—— 你通過 `TheoStream.cancel()` 或傳給 `waitForJob()` 的 `AbortSignal` 主動中止了請求。
* **`TheoUsageError`**（繼承自 `Error`，而非 `TheoApiError`）—— 在發起任何網絡調用之前，因誤用而同步拋出，例如向 `complete()` / `stream()` 傳入 `mode: "research" | "video"`（應改用[異步任務](/guides/async-jobs)方法）。

```typescript theme={null}
import { TheoApiError, TheoTimeoutError, TheoCancelledError, TheoUsageError } from "@hitheo/sdk";

try {
  await theo.complete({ prompt });
} catch (err) {
  if (err instanceof TheoUsageError) { /* fix the call shape */ }
  else if (err instanceof TheoTimeoutError) { console.error(`timed out after ${err.timeoutMs}ms`); }
  else if (err instanceof TheoCancelledError) { /* user aborted — not an error */ }
  else if (err instanceof TheoApiError && err.kind === "network") { /* offline / retry later */ }
}
```

## 流式錯誤

SSE 的 `error` 事件攜帶的**信封結構與 REST 錯誤響應體相同**——兩者可以複用同一套處理邏輯。

```typescript theme={null}
const stream = theo.stream({ prompt: "..." });

for await (const event of stream) {
  if (event.type === "error") {
    const { message, type, code, request_id } = event.data.error;
    throw new Error(`[${type}/${code}] ${message} (request_id=${request_id})`);
  }
  // ...
}
```

這一點與 `0.1.x` 版本不同，當時流式錯誤只有 `{ message }`。完整的信封結構請參見[流式補全](/api-reference/completions/streaming)參考文檔。

## 首次運行診斷

`theo.verify()` 不會直接拋出原始錯誤，而是返回帶有修復建議的結構化診斷結果：

```typescript theme={null}
const result = await theo.verify();
if (!result.authenticated) {
  console.error(result.error);  // underlying error
  console.error(result.hint);   // e.g. "Authentication failed. Confirm your API key..."
}
```

遇到 401 錯誤時，應將此調用作為排查的第一步。常見故障場景請參見[401 故障排查](/troubleshooting/401-errors)。

## 自動重試

SDK 會在以下情況下自動重試：

* **429** —— 觸發限流（遵循 `Retry-After` 響應頭，最多等待 60 秒）
* **5xx** —— 服務器錯誤（指數退避：1 秒、2 秒、4 秒，最長 8 秒）
  客戶端錯誤（400、401、403、404）**不會**被重試。**非冪等的 POST 請求**（`complete`、`research`、`video`）**的超時不會被重試**——重新發起請求可能導致請求被重複執行並重復計費；如果確實需要重試，請自行實現重試邏輯並配合 `Idempotency-Key` 使用。完整的重試模型（包括流式**空閒**超時）請參見[超時與重試](/sdk-reference/timeouts-and-retries)。
  配置方式：

```typescript theme={null}
const theo = new Theo({
  apiKey: "...",
  maxRetries: 3,               // Default: 2
  timeoutMs: 60000,            // Default: 30000 (unary total; stream connect)
  streamIdleTimeoutMs: 180000, // Default: 120000 (between-chunks)
});
```

## 取消請求

`TheoStream.cancel()` 會中止正在進行的流式請求，且不會拋出異常。底層的 `fetch` 會通過 `AbortController` 被中止；後續事件將不再到達，迭代器會正常結束。

```typescript theme={null}
const stream = theo.stream({ prompt: "..." });
setTimeout(() => stream.cancel(), 3000); // Graceful "Stop generating"
for await (const event of stream) { /* ... */ }
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.