錯誤碼
這頁整理呼叫 ExpTech API 時可能遇到的錯誤。錯誤內容依來源不同:驗證與配額失敗沒有內容、OAuth2 回 JSON、SSE 串流回純文字或串流事件。請先看狀態碼,再決定要不要解析內容。
HTTP 狀態碼
Section titled “HTTP 狀態碼”| 狀態碼 | 來源 | 條件 | 回應內容 | 建議處理 |
|---|---|---|---|---|
| 302 | 資料 API | 部分 API 會把 query 轉成標準寫法再導向(見各端點的說明) | 導向 | 跟隨導向(curl -L;fetch 預設會跟隨) |
| 304 | 資料 API | 帶 If-None-Match 且資料沒變 |
無 | 沿用快取 |
| 400 | 資料 API | 參數錯誤(各端點的說明有寫是否會回 400) | 依端點而定 | 修正參數 |
| 400 | SSE | 沒帶 topics,或 topic 名稱不存在 |
純文字 | 修正 topic 名稱 |
| 400 | OAuth2 | 見 OAuth2 錯誤 | JSON | 修正請求 |
| 401 | 需要 token 的 HTTP API | 沒帶 X-Api-Token,或 token 無效、已撤銷 |
無 | 確認 header 名稱與 token |
| 401 | SSE | token 無效或已撤銷(invalid token);需要權限的 topic 沒帶 token(unauthorized) |
純文字 | 確認 token |
| 401 | OAuth2 | client 驗證失敗(JSON invalid_client);userinfo 的 token 無效(無內容) |
JSON 或無 | 確認 client 設定或 token |
| 403 | 需要 token 的 HTTP API | token 沒有該權限;帳號沒訂閱該資源;伺服器暫時查不到配額資料 | 無 | 檢查權限與訂閱 |
| 403 | SSE | forbidden: token scope missing、forbidden: not subscribed |
純文字 | 檢查權限與訂閱 |
| 403 | OAuth2 | too_many_tokens:使用者的 token 已達 25 個 |
JSON | 請使用者刪除不用的 token |
| 404 | 全部 | 路徑不存在;資料不存在(見各端點的說明);指定的節點沒有這條路由(見伺服器與 Base URL) | 無或 HTML 頁面 | 檢查路徑與 host |
| 405 | SSE、權限清單 | 用了 GET 以外的方法 | SSE:method not allowed;權限清單:無 |
改用 GET |
| 429 | 需要 token 的 HTTP API | 今天的配額已用完 | 無 | 臺北時間 00:00 後重試,或提高方案 |
| 429 | SSE | 需要權限的 topic 超過配額(quota exceeded) |
純文字 | 同上;約 60 秒內重連仍會被拒 |
| 429 | OAuth2 | 同一個 IP 呼叫 OAuth2 端點太頻繁(每秒約 4 次,可短暫突發 5 次) | HTML 頁面 | 降低頻率後重試 |
| 500 | OAuth2、資料 API | 伺服器內部錯誤 | JSON 或依端點而定 | 稍後重試 |
| 502、503、504 | 全部 | 伺服器或上游暫時無法服務 | 可能是 HTML 頁面 | 換 host 或稍後重試,見伺服器與 Base URL |
| 503 | SSE | 驗證服務暫時無法連線(auth service unavailable),且這次有要求需要權限的 topic |
純文字 | 稍後重連 |
驗證與配額失敗(無內容)
Section titled “驗證與配額失敗(無內容)”需要 token 的 HTTP API 驗證失敗時,只有狀態碼,沒有 JSON,也沒有 WWW-Authenticate header。各狀態碼的判斷條件見用量與配額。
資料 API 的錯誤
Section titled “資料 API 的錯誤”資料 API(地震、氣象、圖磚等)的錯誤格式依端點而定,寫在各頁的回應與「注意事項」中。共通的情況:
- 很多 API 遇到無效參數時不回 400,而是忽略或改用預設值。請以各頁說明為準。
- 404 與 5xx 可能是 HTML 錯誤頁,不是 JSON。直接
JSON.parse會失敗。
OAuth2 錯誤
Section titled “OAuth2 錯誤”OAuth2 與公開資訊 API 的錯誤是 JSON,格式固定為:
{ "error": "invalid_grant" }這些回應與成功回應一樣以 zstd 壓縮(Content-Encoding: zstd)。
error |
HTTP | 出現在 | 條件 |
|---|---|---|---|
invalid_request |
400 | token、info/oauth-client |
表單無法解析;沒帶 client_id |
invalid_client |
400 | 授權、info/oauth-client |
client_id 不存在 |
invalid_client |
401 | token | client_id 不存在,或機密 client 的 client_secret 錯誤 |
invalid_redirect_uri |
400 | 授權 | redirect_uri 不在該 client 註冊的清單中 |
unsupported_grant_type |
400 | token | grant_type 不是 authorization_code |
invalid_grant |
400 | token | 授權碼不存在、已使用、已過期,或 client_id、redirect_uri、PKCE 不符 |
too_many_tokens |
403 | token | 使用者的 token 已達 25 個 |
server_error |
500 | token | 伺服器內部錯誤 |
redirect_uri 確認合法之後,授權端點的錯誤不回 JSON,而是導回 redirect_uri 並在 query 帶 error:
error |
條件 |
|---|---|
unsupported_response_type |
response_type 不是 code |
invalid_request |
沒帶 code_challenge,或 code_challenge_method 不是 S256 |
invalid_scope |
scope 含有不存在的權限名稱 |
access_denied |
使用者拒絕授權 |
server_error |
伺服器無法建立授權碼 |
GET /api/v1/oauth2/userinfo 失敗時是 401 且沒有內容,不是上面的 JSON。
串流的錯誤與斷線原因
Section titled “串流的錯誤與斷線原因”以下字串是伺服器實際送出的原文,請用完全比對或前綴比對處理。串流協定的細節見即時串流。
連線時就失敗的請求不會開始串流,回應是純文字(結尾有換行)。
| HTTP | 內容 | 條件 |
|---|---|---|
| 400 | topics required, e.g. ?topics=… |
多工入口沒帶 topics |
| 400 | unknown topic: <名稱> |
topic 名稱不存在(大小寫要一致) |
| 401 | invalid token |
帶了 token,但無效或已撤銷。公開 topic 也會被拒 |
| 401 | unauthorized |
需要權限的 topic 沒帶 token |
| 403 | forbidden: token scope missing |
token 沒有該 topic 的權限 |
| 403 | forbidden: not subscribed |
帳號沒有訂閱該資源 |
| 429 | quota exceeded |
該資源今天的配額已用完 |
| 503 | auth service unavailable |
驗證服務暫時無法連線 |
| 405 | method not allowed |
不是 GET |
多工入口(/api/v1/trem/sse?topics=)在全部 topic 都被拒時,內容後面會加上 : <topic>,例如 forbidden: not subscribed: <topic>。只要有一個 topic 通過,連線就會成功(200),被拒的 topic 和原因列在開頭 event: info 的 denied 欄位,原因字串是 unauthorized、forbidden: token scope missing、forbidden: not subscribed、quota exceeded 之一,不加 topic 名稱。
連線中被中斷
Section titled “連線中被中斷”| 事件 | data |
條件 | 建議處理 |
|---|---|---|---|
unsubscribed |
{"topic":"<topic>","reason":"quota exceeded"}(JSON) |
某個需要權限的 topic 超過配額,連線上還有其他 topic | 該 topic 停止傳送,其他照常 |
close |
quota exceeded(純文字) |
連線上最後一個 topic 因超過配額被移除 | 不要立刻重連,等配額恢復 |
close |
token revoked(純文字) |
帳號的任一 token 被撤銷,約 5 秒後關閉該帳號所有已驗證的連線 | 改用仍有效的 token 重連;用已撤銷的 token 會得到 invalid token |
伺服器在寫入逾時(約 30 秒寫不出去)時會直接斷線,不送 close 事件。用戶端應把「沒有 close 的斷線」當成網路問題,依 retry: 3000(3 秒)重連。
