目錄(22 節)
- 點解要認真睇錯誤碼
- 一眼睇晒:錯誤碼對照表
- 4xx 客戶端錯誤:逐層拆解
- 400 系列:請求內容有問題
- 401:key 唔 work
- 403:權限同配額
- 429:慢啲嚟
- 5xx:伺服器端暫時狀態
- 實戰:分清「可重試」同「唔可重試」
- 重試策略:backoff 點寫先啱
- 上 production 前嘅檢查清單
- 除錯三招
- 常見問題 FAQ
- 收到 text_too_long,API 會唔會幫我截斷?
- 點解我嘅 key 一直都係 401?
- 429 同 503 有咩分別,點解兩個都要重試?
- 批量收到 batch_requires_pro 會唔會扣我配額?
- 點解 poll job 冇限流,但提交有?
- 一次批量送 25 項,rate limit 係計 1 次定 25 次?
- 我明明開咗 API key,點解 clone 仲係 403?
- monthly_cap_reached 同帳戶 plan 配額係咪同一件事?
- 開個 Sandbox key,親手試一次錯誤處理
TTS API 錯誤碼對照:400/401/403/429/503 實戰處理
港嘢 TTS API 錯誤碼完整對照同實戰處理策略:分清邊啲錯要改請求、邊啲要重試,同埋點寫 backoff 先啱。
一句答你: 港嘢 TTS API 嘅錯誤碼分三層——HTTP status(400/401/403/429/503)、
code字串、同 optional 嘅補充欄位;大部分 400/401/403 係「改完再送」就得,只有 429 同 503 應該加 backoff 重試。
Key Takeaways
- 睇 HTTP status 分辨大類:4xx 多數係你嘅請求或權限問題,5xx 係伺服器端暫時狀態
code字串先係你要 switch 嘅目標,唔好只靠 status code- 400 系列:
text_too_long、clone_not_supported_sync、srt_not_supported_sync、too_many_items呢類,改請求即刻可以重送- 401 / 403:key 或 scope 問題,重試冇用,要先換 key 或者開對 scope
- 429 同 503 係唯二值得自動重試嘅類別;429 跟
Retry-After,503 用指數退避
點解要認真睇錯誤碼
好多開發者接 TTS API 嘅第一版,都係「送咗先算」——成功就攞 audio,失敗就當成網絡問題一路 retry。呢種做法喺 demo 階段無問題,但一上 production 就會出事:
- 明明係請求內容錯(例如文字太長),retry 一百次都係錯,白白燒配額同時間
- 明明係 key 過期,retry 只會不停收 401,log 全部係噪音
- 明明係撞到限流,但唔跟
Retry-After硬重試,只會令情況更差
所以錯誤處理唔係「有就得」,而係要分得清邊啲錯係「可以重試」、邊啲係「要改請求」。呢篇就係一份對照表加實戰策略。
一眼睇晒:錯誤碼對照表
港嘢 API 用標準 HTTP status,配一個機器可讀嘅 code 字串。下表係完整對照(來源:公開 API 文件錯誤表):
| HTTP | Code | 意思 | 應對 |
|---|---|---|---|
| 400 | text_required | 冇帶 text | 補返文字,1–500 字符 |
| 400 | text_too_long | 文字超過 500 字符 | 縮短文字(唔會幫你截斷) |
| 400 | clone_not_supported_sync | sync 端點唔支援 clone | 改用 async job |
| 400 | srt_not_supported_sync | sync 端點唔支援 SRT | 改用 async job |
| 400 | invalid_items | 批量有項目驗證失敗 | 修正有問題嘅項目(全有或全無) |
| 400 | too_many_items | 批量超過 25 項 | 分拆成多個請求 |
| 401 | invalid_or_expired_token | key 無效/過期/被 revoke | 換一把有效 key |
| 403 | insufficient_scope | 缺 scope(例如 clone 要 tts:clone) | 開返對應 scope 嘅 key |
| 403 | monthly_cap_reached | key 月度字符上限到 | 等新週期或提高上限(body 有 used) |
| 403 | batch_requires_pro | 批量係專業/工作室專屬 | 升級方案或改逐個提交 |
| 429 | rate_limit_exceeded | 每 key 每分鐘限流(預設 60/min) | 跟 Retry-After 重試 |
| 429 | in_flight_limit_reached | 在途任務達到方案上限 | 等現有 job 完成再送 |
| 503 | pool_cold | sync speech 端點暫時未就緒 | 改用 async,或稍後退避重試 |
4xx 客戶端錯誤:逐層拆解
400 系列:請求內容有問題
400 係最常見嘅一類,全部都可以「改完即刻重送」,唔需要等。
文字相關。 text_required 代表你冇帶 text 欄位;text_too_long 代表文字超過 500 字符。留意 API 係 rejected,唔會截斷——唔似得啲寬鬆嘅服務幫你靜靜切走尾段,你收到 400 就係要自己縮短。
sync 限制。 港嘢 API 有一個 ≤300 字符嘅 sync 捷徑,但佢只支援 voice 同 design 兩種模式。如果你想用 sync 去出 clone,會回 clone_not_supported_sync;想出 SRT,會回 srt_not_supported_sync。兩個都係提你「呢件事要行 async 軌」。sync 同 async 嘅分別,可以睇 粵語 TTS API 快速上手。
批量。 too_many_items 代表你一次過送嘅 request bodies 超過 25 個;invalid_items 代表批量入面有項目驗證失敗。批量驗證係 全有或全無——只要有任何一項無效,成批都唔會提交,所以你收到 invalid_items 時要逐項檢查,而唔係假設「好嘅嗰幾項已經入咗」。批量嘅正確做法可以睇 批量生成工作流。
401:key 唔 work
invalid_or_expired_token 係一把 key 已經無效——可能係打錯、過期、或者被 revoke。呢個錯重試冇用,因為 key 唔會自己變返有效。正確做法係換 key 再送。
記住港嘢 key 有兩個前綴:sk_live_(正式)同 sk_test_(沙盒)。原始 key 只會顯示一次,server 只存 SHA-256 hash,所以你唔可以「再睇返」舊 key,唔見咗就要重新開一把。
403:權限同配額
403 係「你身份 OK,但呢件事你唔准做或者做唔到」。三個 code 各有唔同應對:
insufficient_scope:你嘅 key 缺某個 scope。最經典係 clone——tts:generate唔包括 clone,要另外開tts:clone。clone 嘅完整流程可以睇 粵語聲音複製指南。monthly_cap_reached:key 嘅月度字符上限到咗。response body 會帶used欄位,方便你出告警。呢個唔係 API 壞,係你設嘅 quota 到頂。batch_requires_pro:批量(帶items)係專業/工作室方案專屬。免費同入門用戶帶items會零提交、零扣費——即係話唔會白白燒你配額,但你要改用逐個提交,或者升級。
429:慢啲嚟
429 係唯一「重試係正確做法」嘅 4xx。港嘢有兩種 429:
rate_limit_exceeded:每 key 每分鐘嘅滑動窗口限流,預設 60/min。留意佢係計成功嘅 billable 請求;讀取 endpoint(例如 poll job、攞聲線目錄)唔限流。回應會帶Retry-After秒數,跟住等就啱。in_flight_limit_reached:在途任務達到方案上限。各方案上限唔同:免費 3、入門 5、專業 10、工作室 20。呢個唔係「你送得太快」,而係「你同時排咗太多未完成嘅 job」。
批量有個細節:一次批量請求只計一次限流,唔係逐項計。所以由「逐個送」改成「批量送」,對 rate limit 反而更友好。
5xx:伺服器端暫時狀態
pool_cold(503)係 sync speech 端點嘅暫時狀態。呢個唔係你嘅請求問題,係伺服器端未 ready。因為 async 軌冇呢個限制,生產 pipeline 應該以 async 為主——sync 只留返做 ≤300 字符嘅即時小實驗。
遇到 503 嘅正確做法係指數退避重試,而唔係即時硬打。同步地,poll job 嘅時候如果偶爾撞到 5xx,都可以用同一套退避邏輯。
實戰:分清「可重試」同「唔可重試」
錯誤處理嘅核心一句:4xx(除 429)唔好重試,529 同 503 先重試。
| 類別 | 可唔可以自動重試 | 做法 |
|---|---|---|
| 400 | 唔可以 | 改請求再送 |
| 401 | 唔可以 | 換 key |
| 403 | 唔可以 | 開 scope/升級/等週期 |
| 429 | 可以 | 跟 Retry-After |
| 503 | 可以 | 指數退避,上限幾次 |
一個實用嘅判斷流程(pseudo code,唔使照抄):
on error:
if status == 429: sleep(Retry-After header 或 1s); retry
elif status == 503: sleep(backoff); retry (最多 N 次)
elif status == 401: 換 key,唔 retry 同一把
elif status == 403: 記錄 code,按 code 決定開 scope / 升級 / 等
elif status == 400: log code + 請求內容,改請求再送,唔盲 retry
else: 當未知錯誤,log 完整 body,人手查
重試策略:backoff 點寫先啱
知道邊啲錯可以重試之後,下一個問題係「點重試」。最差嘅做法係「即刻再打」——咁樣只會令限流更嚴重,甚至觸發更長嘅冷卻。正式嘅做法係指數退避(exponential backoff):
- 第一次失敗等 0.5 秒,第二次等 1 秒,第三次等 2 秒,如此類推,設一個上限(例如最多 5 次、總等待唔超過 30 秒)
- 每次等待加少量隨機抖動(jitter),避免幾百個 client 同步 retry 造成「驚群效應」
- 一旦收到 429 帶
Retry-After,就以伺服器講嘅秒數為準,唔好自己估
⚠️ 一個好易踩嘅陷阱:POST 唔係 idempotent。 GET 重試安全,因為讀幾多次結果一樣;但你重試一個「生成請求」POST,有機會變成送兩個 job——如果你嘅請求其實第一次已經成功,只係 response 途中斷線,盲重試就會重複扣字符。所以:
- 提交請求時,如果係 timeout 或者網絡中斷(唔係收到 4xx/5xx),唔應該即刻盲重試
- 穩陣做法係加一個 client 自己嘅冪等鍵(例如用 UUID 記住今次提交),或者提交後先 poll 一次確認狀態,再決定要唔要補送
呢個原則同「批量全有或全無」係一體兩面:API 本身幫你確保批量唔會半途而廢,但你嘅 client 都要確保唔會自己送多咗。
上 production 前嘅檢查清單
呢份清單係上線前後都值得逐項對一次,避免最常見嘅錯誤處理漏洞:
- 每個
code都有對應分支 — 唔好只用if (res.ok)兩條路。最起碼要分開「改請求」「換 key」「開 scope」「重試」四類。 - 429 一定跟
Retry-After— 唔好寫死一個秒數。 - 5xx 有退避上限 — 避免無限重試拖死 worker。
- log 有
code同job_id— 出事時可以對返具體係邊個 job。 - 區分 sync 同 async 嘅錯誤預期 — sync 會有
pool_cold,async 唔會;唔好一套邏輯行晒兩條軌。 - 批量前先本地驗證 — 因為批量係全有或全無,本地先檢查每項係咪符合規格,可以慳一個來回。
把呢六點做齊,你嘅 TTS 整合就唔會「一撞錯就當網絡問題」,而係可以準確咁話返自己知:今次究竟要改乜。
除錯三招
第一,log 完整 body。 港嘢嘅錯誤回應會帶 c嗰啲e 同有時補充欄位(例如 used、limit、active)。淨係 log status code 會 miss 咗最有用嘅資訊。
第二,分開 key。 開發用一把 key,production 用另一把。咁樣撞 rate limit 或者誤觸 revoke 都唔會互相影響。
第三,先估類別再重試。 如果 log 顯示同一條請求反覆收 400,就唔係網絡問題,係請求本身有錯。愈早接受呢件事,愈快修好。
想睇埋成本同配額點連埋一齊,可以睇 粵語 TTS 定價攻略。
常見問題 FAQ
收到 text_too_long,API 會唔會幫我截斷?
唔會。text_too_long 係 rejected——成個請求唔會提交,你要自己縮短到 500 字符以內再送。呢個設計係為咗避免「靜靜切走尾段」引致內容唔完整。
點解我嘅 key 一直都係 401?
因為 401(invalid_or_expired_token)代表把 key 本身無效——可能打錯、過期或者被 revoke。重試同一把無效 key 唔會成功,要重新開一把新 key。留意原始 key 只顯示一次,記得即時保存。
429 同 503 有咩分別,點解兩個都要重試?
429 係「你太快/同時排太多」,伺服器本身正常;503(pool_cold)係伺服器端暫時未 ready。兩者都係暫時狀態,所以都值得重試;但 429 要跟 Retry-After,而 503 用指數退避就啱。
批量收到 batch_requires_pro 會唔會扣我配額?
唔會。免費同入門方案帶 items 嘅請求會零提交、零扣費,只係回一個 403 提你批量係專業/工作室專屬。你可以改為逐個提交,或者升級方案。
點解 poll job 冇限流,但提交有?
港嘢只對成功嘅 billable 生成請求計 rate limit——提交(生成)會扣字符、會計限流;而讀取(poll job、攞聲線目錄)唔消耗資源,所以唔限流。所以你可以放心頻繁 poll,唔會因此撞 429。
一次批量送 25 項,rate limit 係計 1 次定 25 次?
計 1 次。批量請求只計一次限流,唔係逐項計。所以大批量反而比「逐個送」更慳 rate limit 額度。
我明明開咗 API key,點解 clone 仲係 403?
因為 scope 唔啱。預設 key 帶 tts:generate,但 clone 要獨立嘅 tts:clone scope。你開 key 嗰陣要明確揀 clone scope,否則無論送幾多次都會回 insufficient_scope。
monthly_cap_reached 同帳戶 plan 配額係咪同一件事?
係兩層。每個 key 可以另外設一個月度字符上限(預設無上限),去到就回 403 monthly_cap_reached,response body 帶 used 方便你出告警。呢個係 key 層嘅保護,同你帳戶 plan 嘅月配額分開計。
[!CTA]
開個 Sandbox key,親手試一次錯誤處理
唔使自己撞板——用免費 Sandbox key 送幾個故意出錯嘅請求,睇下每個 code 點回應,再寫你嘅 retry 邏輯。