錯誤碼
呼叫失敗時返回 4xx 或 5xx 狀態碼和統一的錯誤物件。程式按 HTTP 狀態碼、code 和 details 判斷怎麼處理;message 是給人看的說明,文字可能調整,不要用它做判斷。
| 要做什麼 | 看哪裡 |
|---|---|
| 瞭解錯誤物件的欄位 | 錯誤響應的結構 |
查一個 code 的含義 | 錯誤碼列表 |
查 details.reason 的含義 | details 的取值 |
| 決定要不要重試 | 錯誤處理建議 |
message 的語言由請求頭 Accept-Language 選擇(簡體中文、繁體中文或英語),響應帶 Content-Language 和 Vary: Accept-Language。語言不影響錯誤碼、許可權和是否可以重試,見語言與本地化。
錯誤響應的結構
{
"error": {
"code": "rate_limited",
"message": "群消息过于频繁,请稍后再试",
"details": { "reason": "group_send_rate" },
"request_id": "GNBHUXHA426Q3YLRLCJOWY7ISK"
}
}| 欄位 | 型別 | 說明 |
|---|---|---|
error.code | String | 錯誤碼,見錯誤碼列表 |
error.message | String | 給人看的說明,語言見上文。同一個 code 在不同情況下的 message 可能不同,如 404 not_found 的“使用者不存在”“介面不存在” |
error.details | Object | 附加資訊,只有部分錯誤返回,沒有時不返回這個欄位。最常見的是 reason,說明具體原因,見 details 的取值 |
error.request_id | String | 這次請求的 ID,與響應頭 X-Request-ID 相同,排查問題時請提供它 |
錯誤響應還可能帶以下響應頭:
| 響應頭 | 說明 |
|---|---|
X-Request-ID | 每個響應都帶,包括成功的響應。請求頭中帶了合法的 X-Request-ID 時原樣返回,否則由服務端生成,見請求頭 |
Retry-After | 429 時返回,需要等待的秒數,為整數,至少為 1 |
Allow | 405 時返回,這個路徑支援的請求方法,如 POST |
批次介面中單項的失敗不使用這個結構:整個請求返回 200 OK,失敗的項各自帶 code、message 和 details(有時才返回),取值與本頁相同。例如批次新增群成員時:
{
"changed": false,
"member_version": 3,
"results": [
{ "username": "e-u4", "code": "permission_denied", "message": "该用户在群黑名单中", "details": { "reason": "group_blacklisted" } },
{ "username": "alice", "code": "limit_exceeded", "message": "群人数已达上限", "details": { "reason": "group_member_limit" } }
]
}錯誤碼列表
以下是 OpenAPI 可能返回的全部錯誤碼。各介面特有的情況見對應介面文件的“錯誤”一節。
| HTTP 狀態碼 | code | 含義 |
|---|---|---|
| 400 | invalid_argument | 引數缺失、格式不對或超出取值範圍;請求體不是單個 JSON 物件、Content-Type 不是 application/json、含有介面不認識的欄位或欄位型別不對;分頁遊標無效。message 會指出是哪個引數,部分介面另在 details 中給出原因 |
| 401 | unauthenticated | 缺少 Authorization 請求頭,或 App Token 無效、已過期、已失效。重新換取 App Token 後重試;details.reason 為 app_deleted 或 tenant_closed 時不要重試,見使用和快取 App Token |
| 401 | invalid_client | 換取 App Token 時 Client ID 或 Client Secret 錯誤,或者 org_name、app_name 不存在(包括應用已刪除、租戶已登出) |
| 403 | permission_denied | App Token 不屬於路徑中的應用;或者業務規則不允許這項操作,如把群黑名單中的使用者加入群,details.reason 說明原因 |
| 403 | ip_not_allowed | 來源 IP 不在應用的 IP 白名單內 |
| 403 | tenant_unavailable | 租戶已暫停或處於登出冷靜期,見應用和租戶的狀態 |
| 403 | app_unavailable | 應用已停用或被暫停服務;或應用處於只讀狀態,不能執行這項寫操作 |
| 403 | user_disabled | 使用者已被封禁,不能為他簽發登入憑證;或者以被平臺封禁的使用者身份傳送訊息,此時 details.disabled_by 為 platform |
| 403 | not_group_member | 指定的使用者不是該群的成員,如以非成員的身份傳送群訊息、設定非成員的群內角色;為使用者設定群免打擾時,使用者不是成員或群已解散 |
| 403 | group_disabled | 群已被封禁,不能執行這項操作(如新增成員),details.disabled_by 為 tenant(你封禁的)或 platform(平臺封禁的) |
| 403 | chatroom_disabled | 聊天室已被封禁,不能執行這項操作(如傳送訊息),details.disabled_by 為 tenant(你封禁的)或 platform(平臺封禁的) |
| 403 | message_rejected | 訊息沒有透過傳送前的檢查,沒有發出或儲存:被內容安全拒絕,或被你的同步回撥拒絕。傳送訊息、編輯訊息、批次傳送訊息(作為每個接收人的結果)和傳送聊天室訊息時都可能返回,details.reason 說明原因 |
| 403 | content_rejected | 資料或申請的內容(如暱稱、群名稱、好友申請的附言)沒有透過內容安全檢查,沒有寫入,details.field 指出欄位,見內容安全 |
| 403 | file_blocked | 檔案因違規已被遮蔽,不能下載,也不能由你刪除。刪除被遮蔽的檔案時返回;換取下載地址時作為單項的結果返回,見下載與管理檔案 |
| 404 | not_found | 資源不存在,如使用者、群、會話、訊息、聊天室不存在或已刪除;聊天室已解散時 details.reason 為 chatroom_dismissed;message 為“介面不存在”時,是請求的路徑寫錯了 |
| 405 | method_not_allowed | 路徑存在,但不支援這個請求方法,響應頭 Allow 列出支援的方法 |
| 409 | conflict | 資源或冪等狀態衝突,見獨立 RTC 頻道 |
| 409 | already_exists | 要建立的資源已存在,如使用者名稱已被佔用 |
| 409 | version_conflict | 請求中的 version 與當前版本不一致,資料已被其他請求修改,見併發修改與 version;上傳檔案時表示上傳當前的狀態不允許這項操作,見檔案介面 |
| 409 | limit_exceeded | 超出數量上限,如好友數、群人數、應用的儲存額度,details.reason 說明是哪一項;應用的註冊使用者數已滿時沒有 details。註冊使用者數、群總數、儲存容量等應用級的上限由應用的套餐決定 |
| 409 | stream_in_progress | AI 對話:會話中已有正在生成的回覆,details.stream_id 為它的 ID;可以用 replace 先結束它 |
| 409 | stream_closed | AI 回覆已結束(使用者停止、超時、被替換等),不能再寫入;details.reason 為結束後的狀態,details.finish_reason 為結束原因。收到後停止呼叫模型 |
| 409 | seq_gap | AI 回覆的增量序號不連續,或結束時的 last_seq 不等於已接受的最後一段;details.expected_seq 為期望的下一個序號 |
| 410 | file_expired | 檔案已過期或已被刪除。換取下載地址時作為單項的結果返回;刪除約 30 天后,同一個檔案地址改為返回 not_found |
| 413 | payload_too_large | 請求體超過 1 MiB;或者訊息內容超過應用的訊息大小上限、建立上傳時檔案的大小超過這種用途和型別的上限,此時 details.max_bytes 為上限的位元組數 |
| 429 | rate_limited | 請求過於頻繁,超出了呼叫額度或頻率限制,按響應頭 Retry-After 等待後重試,見限流與應用狀態 |
| 500 | internal | 服務內部錯誤,具體原因不返回給呼叫方。可以稍後重試(帶 Retry-After 時按它等待),持續出現時請帶上 request_id 聯絡我們 |
| 503 | unavailable | 服務暫時不可用,按 Retry-After 等待後重試,見獨立 RTC 頻道 |
details 的取值
details 中的欄位因錯誤碼而不同,下面列出 OpenAPI 可能返回的取值。以後可能增加新的取值,遇到不認識的取值時按 code 處理即可。
令牌與服務狀態
code | details | 說明 |
|---|---|---|
unauthenticated | reason 為 app_deleted | 應用已被刪除,App Token 永久失效,換取也會失敗。請停止呼叫並清除儲存的憑據 |
unauthenticated | reason 為 tenant_closed | 租戶已登出,處理同上 |
tenant_unavailable | reason 為 arrears | 租戶只因欠費被暫停服務,結清欠費後恢復,見逾期與欠費 |
app_unavailable | reason 為 arrears | 租戶欠費,應用處於只讀狀態:可以查詢,不能執行新增資料的寫操作,結清欠費後恢復,見逾期與欠費 |
tenant_unavailable、app_unavailable 不帶 details 時,是租戶或應用被停用、暫停,或被平臺設為只讀,可以在控制檯檢視租戶和應用的狀態,見應用和租戶的狀態。
數量上限
limit_exceeded 的 details.reason,各項的數值見使用限制。其中應用的群總數、儲存容量、聊天室數(以及沒有 details 的註冊使用者數)由應用的套餐決定,群人數、使用者加入的群數也不超過套餐的額度,見套餐的額度:
details.reason | 說明 |
|---|---|
friend_limit | 使用者的好友數已達上限 |
peer_friend_limit | 對方的好友數已達上限 |
blacklist_limit | 使用者的黑名單人數已達上限 |
group_member_limit | 群人數已達上限 |
user_group_limit | 使用者加入的群數已達上限 |
app_group_limit | 應用中未解散的群數已達套餐的額度,不能再建群 |
admin_limit | 群或聊天室的管理員人數已達上限 |
group_blacklist_limit | 群黑名單人數已達上限 |
pinned_message_limit | 會話中置頂的訊息數已達上限 |
edit_limit | 這條訊息的編輯次數已達上限 |
storage_quota | 應用的儲存用量加上這次上傳的大小超過了儲存額度(平臺配額與套餐儲存容量中較小的一個),另帶 limit_bytes(額度)和 used_bytes(當前用量),單位為位元組 |
group_file_limit | 群檔案已滿 1000 個 |
chatroom_limit | 應用中未解散的聊天室數已達上限(平臺配額 chatroom_limit 與套餐的聊天室數中較小的一個),不能再建立聊天室 |
mute_limit | 聊天室的禁言名單已滿 1 萬個,在批次介面中作為單項的結果返回 |
ban_limit | 聊天室的封禁名單已滿 1 萬個,在批次介面中作為單項的結果返回 |
allowlist_limit | 聊天室的白名單已滿 500 人,在批次介面中作為單項的結果返回 |
attribute_limit | 寫入後聊天室屬性的個數或合計大小超出上限,在設定屬性的結果中作為沒有寫入的鍵的原因返回 |
conversation_setting_limit | 使用者的會話免打擾已有 10000 個 |
word_list_limit | 應用的詞庫已有 20 個 |
word_limit | 新增後詞庫超過 10000 個詞條,或應用合計超過 50000 個,這一批都沒有新增 |
penalty_rule_limit | 自動處罰規則超過 5 條 |
app_bots | 應用的 AI 機器人數已達上限(100 個) |
bot_active_streams | 這個機器人同時生成的回覆數已達上限(機器人的 max_active_streams) |
頻率限制
rate_limited 的 details.reason,等待的時間都在響應頭 Retry-After 中:
details.reason | 說明 |
|---|---|
不帶 details | 應用的 OpenAPI 呼叫額度已用完,或超出了其他頻率限制(如換取 App Token、計算密碼雜湊) |
group_send_rate | 這個群每秒的訊息數已達上限 |
app_message_rate | 應用每分鐘的訊息數已達配額 |
image_busy | 完成上傳時圖片處理繁忙,檔案仍在上傳中,稍後重新呼叫完成上傳即可 |
room_send_rate | 這個聊天室或應用全部聊天室每秒的訊息數已達上限。只對普通和高優先順序的訊息返回,低優先順序的訊息超出時被丟棄,不返回錯誤 |
room_attribute_rate | 這個聊天室每秒的屬性寫入已達 20 次 |
request_rate | 代使用者舉報超過每個應用每分鐘 600 次 |
ai_write | 應用每秒寫入的 AI 回覆增量已達 5000 段 |
許可權
permission_denied 的 details.reason:
details.reason | 說明 |
|---|---|
group_blacklisted | 使用者在群黑名單中,不能加入這個群 |
not_editable | 只能編輯文字訊息和自定義訊息 |
message_recalled | 訊息已被撤回或擦除,不能編輯或置頂 |
owner_protected | 不能禁言、移出或封禁聊天室的所有者,在批次介面中作為單項的結果返回。請先轉讓或清空所有者 |
target_banned | 要設為聊天室管理員的使用者正在被這個聊天室封禁 |
not_revisable | 稽核記錄當前的狀態不能作出結論、改判或轉交,如把無違規改為違規、改判超過 30 天、記錄已轉交平臺或已經結束,見作出結論 |
app_rejected | 客戶端傳送好友申請、加群時被你的加好友前、加群前回撥拒絕,message 是你的服務端給出的提示,另帶 app_reason,見同步回撥 |
callback_unavailable | 加好友前、加群前回撥失敗(超時、接收端故障等),按失敗策略拒絕了這項操作,另帶 app_reason(為 null),見同步回撥 |
解封或解散被平臺封禁的聊天室時,返回不帶 details 的 permission_denied,這樣的聊天室只能由平臺處理。
訊息介面的引數錯誤
訊息相關介面返回 invalid_argument 時,details.reason 說明具體原因:
details.reason | 說明 |
|---|---|
unknown_type | 不支援的訊息型別 |
invalid_body | 訊息內容不符合該型別的要求,details.field 指出欄位 |
invalid_client_msg_id | client_msg_id 不是 1 到 64 個可見 ASCII 字元 |
reserved_client_msg_id | client_msg_id 以系統保留的 evt_ 或 sys_ 開頭 |
invalid_recipient | to_user 和 to_group 沒有恰好給出一個 |
from_required | 傳送單聊訊息或批次傳送時沒有給出 from |
self_conversation | 給自己傳送訊息 |
mentions_not_allowed | 在單聊中 @ 使用者 |
invalid_reply | 引用的訊息不存在、不可見或已撤回;或在批次傳送中引用訊息 |
receipt_not_allowed | 在單聊中,或以系統身份傳送時要求已讀回執 |
invalid_online_only | 只推線上的訊息不是 custom 型別,或帶了不允許的欄位 |
invalid_push | push 不是 JSON 物件、含有 disabled、force、title、body、ext 以外的欄位、取值不符合要求(如 disabled 和 force 同時為 true)或超過 2 KB,details.field 指出欄位,見傳送訊息時的 push 欄位 |
too_many_items | 一次提交的數量超過上限,details.field 為引數名,details.max 為上限 |
empty_edit | 編輯訊息時 body 和 ext 都沒有給出 |
conflicting_params | 拉取訊息時 after_seq、before_seq、around_seq 給出了多個 |
檔案介面
上傳檔案和下載與管理檔案的介面返回 invalid_argument 時,details.reason 說明具體原因:
details.reason | 說明 |
|---|---|
invalid_purpose | 這個介面不能上傳這種用途,或用途與型別 kind 不匹配 |
invalid_name | 檔名為空或不符合規則 |
unsupported_type | 完成上傳時按檔案內容識別出的格式不符合型別,details.content_type 為識別出的格式 |
size_mismatch | 上傳的內容大小與建立上傳時宣告的不同。重新上傳內容後再完成即可 |
upload_incomplete | 內容還沒有上傳,或分片不全、大小不對。上傳完整後再完成即可 |
image_too_large | 圖片超過 5000 萬畫素 |
invalid_image | 圖片無法解碼 |
upload_failed | 這次上傳已經因格式不符、群檔案已滿等原因失敗,重試完成也不會成功,需要重新建立上傳 |
version_conflict 的 details.reason:
details.reason | 說明 |
|---|---|
upload_completed | 上傳已經完成,不能再取消、索取分片的上傳地址或查詢已上傳的分片。要刪除已完成的檔案請呼叫刪除檔案 |
upload_changed | 完成上傳的過程中,內容又被重新上傳了。重新呼叫完成上傳即可 |
upload_completing | 另一個完成上傳的請求正在處理這個檔案,稍後重試 |
聊天室介面的引數錯誤
聊天室的介面返回 invalid_argument 時,details.reason 說明具體原因。傳送聊天室訊息時,訊息內容的錯誤與訊息介面相同(如 unknown_type、invalid_body):
details.reason | 說明 |
|---|---|
invalid_priority | priority 不是 high、normal、low 之一 |
invalid_attribute_key | 屬性的鍵不合法或重複,details.key 指出鍵 |
invalid_attribute_value | 屬性的值不是字串、超過 4096 位元組或包含控制字元,details.key 指出鍵 |
attributes_too_large | 一次設定的鍵和值合計超過 16 KB,details.max_bytes 為上限 |
auto_delete_not_allowed | 服務端設定的屬性不能標記 auto_delete |
推送介面的引數錯誤
推送裝置與設定的介面返回 invalid_argument 時,details.reason 說明具體原因:
details.reason | 說明 |
|---|---|
invalid_duration | 免打擾的時長不在 1 到 315360000 秒(10 年)之間 |
invalid_quiet_hours | 夜間免打擾的時刻格式不對,或開始等於結束 |
invalid_timezone | 時區不是 IANA 時區名稱 |
invalid_preview | 預覽方式不是 full、sender_only、none |
invalid_mode | 會話免打擾的 mode 缺失或取值不對,或單聊設定了 mention_only |
self_conversation | 單聊免打擾的對方是使用者本人 |
內容安全
內容沒有透過內容安全檢查時,訊息類的介面返回 403 message_rejected,資料和申請類的介面返回 403 content_rejected,details 的取值:
details | 說明 |
|---|---|
reason 為 sensitive_content | 命中了拒絕的詞庫 |
reason 為 provider_block | 第三方稽核判定違規;開啟了頭像稽核時,頭像的地址不能公開訪問或是已被遮蔽的檔案 |
reason 為 check_timeout | 已停用:第三方稽核只在傳送、儲存之後進行,不再返回 |
field | 只在 content_rejected 中返回,為被拒絕的欄位,多個欄位被拒絕時為其中的第一個:使用者資料為 nickname、avatar_url;群資料為 name、description、announcement、avatar_url;群暱稱為 group_nickname;入群申請為 message、reason;好友申請為 message、add_source;聊天室資料為 name、description、announcement |
批次傳送訊息時,被拒絕的訊息在每個接收人的結果中都返回 message_rejected;批次建立使用者時,被拒絕的使用者出現在 failed 中,code 為 content_rejected,沒有 details。這兩個錯誤重試同樣的內容不會成功,請提示使用者修改內容。
稽核配置與詞庫和稽核記錄與違規的介面返回 invalid_argument 時,details.reason 的取值:
details.reason | 說明 |
|---|---|
unsupported_scene | 場景不支援這種稽核方式,如在訊息和聊天室訊息以外的場景使用發出後的第三方文字稽核 |
provider_account_required | 開啟了第三方稽核,但應用還沒有在控制檯選擇稽核賬號 |
unsupported_action | 遮蔽詞庫沒有給出處理方式 action,或放行詞庫給出了 action |
invalid_action | 結論中的處置不適用於這個物件,如對使用者資料撤回訊息;或者無違規的結論帶了處置 |
self_report | 代使用者舉報時,舉報人舉報自己或自己的訊息 |
invalid_evidence | 代使用者舉報時證據訊息不符合要求:舉報的不是使用者或群卻附了證據訊息;證據訊息不存在、舉報人看不到、已撤回,不是被舉報的使用者發的,或不在被舉報的群裡 |
同步回撥
操作被你的同步回撥拒絕時,發訊息前、發聊天室訊息前回撥返回 403 message_rejected,加好友前、加群前回撥返回 403 permission_denied,details 相同:
details | 說明 |
|---|---|
reason 為 app_rejected | 你的服務端拒絕了這項操作,message 是你給出的提示(沒有給出時為“訊息傳送失敗”或“操作被拒絕”) |
reason 為 callback_unavailable | 同步回撥失敗(超時、連線失敗、響應無效等),按你設定的失敗策略“拒絕”處理,見失敗時的處理 |
app_reason | 你在響應中給出的原因程式碼,沒有給出時以及 callback_unavailable 時為 null |
同步回撥預設只對使用者在客戶端的操作呼叫。你的服務端傳送訊息(包括聊天室訊息)、編輯訊息時,只有對應的同步回撥在呼叫條件 vias 中包含了服務端的操作才會呼叫;服務端新增好友、加人不呼叫加好友前、加群前回撥。批次傳送訊息時只呼叫一次,被拒絕時每個接收人的結果都是 message_rejected。
AI 對話
AI 對話的介面和機器人賬號:
code | details.reason | 說明 |
|---|---|---|
invalid_argument | not_bot | 開始回覆時 bot 不是機器人 |
invalid_argument | recipient_is_bot | 開始回覆時接收者是機器人 |
invalid_argument | invalid_ops | 增量格式不對:片段的 index 跳號、向非文字片段追加、片段超過 200 個 |
permission_denied | bot_disabled | 機器人已停用,不能開始回覆 |
permission_denied | bot_account | 對機器人執行了不允許的操作:簽發登入憑證、修改密碼、把機器人加入群 |
payload_too_large | line / content | 一段增量超過 64 KB;或一條回覆累計寫入超過 1 MB(回覆同時以 failed 結束) |
其他欄位
code | details | 說明 |
|---|---|---|
not_group_member | reason 為 leave_pending | 以使用者的身份讀取或操作群會話時,該使用者剛離開群,相關處理還沒完成。通常幾秒後即可讀到他離開前的訊息,可以稍後重試 |
internal | reason 為 dependency_unavailable | 依賴的服務暫時不可用,按響應頭 Retry-After 等待後重試:查詢線上狀態時(5 到 30 秒);查詢聊天室成員、移出聊天室成員、傳送和撤回聊天室訊息、查詢最近的聊天室訊息時(1 到 5 秒)。傳送聊天室訊息時訊息沒有發出,用同一個 client_msg_id 重試即可 |
user_disabled | disabled_by 為 platform | 使用者被平臺封禁,服務端不能以他的身份傳送訊息(包括聊天室訊息);被你封禁的使用者仍然可以 |
group_disabled | disabled_by 為 tenant 或 platform | 群被誰封禁:tenant 為你(透過 OpenAPI 或控制檯)封禁,platform 為平臺封禁 |
chatroom_disabled | disabled_by 為 tenant 或 platform | 聊天室被誰封禁,含義同上 |
not_found | reason 為 chatroom_dismissed | 聊天室已解散。解散後 30 天內仍可以查詢聊天室資訊,其他介面返回這個錯誤,據此可以區分“已解散”和“不存在” |
payload_too_large | max_bytes | 應用的訊息大小上限,或這種用途的檔案大小上限,單位為位元組 |
invalid_argument | field | 出錯的欄位,如訊息內容中的欄位、線上狀態查詢的 usernames |
invalid_argument | reason 為 invalid_date_range | 查詢通話統計時缺少 from 或 to、格式不是 YYYY-MM-DD、to 早於 from,或超過 92 天 |
控制檯和客戶端介面的錯誤碼
以下錯誤碼不會由 OpenAPI 返回,只出現在控制檯和客戶端介面(使用者以 User Token 呼叫的介面)中,列在這裡供參考:
| HTTP 狀態碼 | code | 含義 |
|---|---|---|
| 400 | invalid_code | 驗證碼、兩步驗證動態碼或恢復碼錯誤或已失效 |
| 401 | invalid_credentials | 賬號或密碼錯誤,或使用者的登入憑證無效、已使用、已過期 |
| 401 | mfa_required | 控制檯登入時還需要輸入兩步驗證動態碼 |
| 401 | session_revoked | 使用者的登入會話已被吊銷,如在其他裝置登入被擠下線、被踢下線、修改了密碼,details.reason 給出原因,見下線原因 |
| 403 | reauth_required | 控制檯的敏感操作(如新增推送憑據、新建回撥地址)需要先重新驗證身份 |
| 403 | captcha_required | 需要先完成圖形驗證 |
| 403 | mfa_setup_required | 租戶要求全員開啟兩步驗證,當前賬號尚未開啟 |
| 403 | invitation_target_mismatch | 當前賬號與邀請的郵箱或手機號不一致 |
| 403 | user_muted | 使用者被全域性禁言,不能傳送 |
| 403 | user_blocked | 因黑名單不能執行這項操作。傳送好友申請時 details.by 為 self(你拉黑了對方)或 peer(對方拉黑了你);傳送單聊訊息時只會是 peer |
| 403 | friend_add_denied | 對方設定了拒絕任何人新增好友 |
| 403 | not_friend | 應用開啟了只能給好友發訊息或只允許邀請好友入群,雙方不是好友 |
| 403 | group_muted | 在群裡被禁言,或群開啟了全員禁言 |
| 403 | not_chatroom_member | 使用者的這條連線不在聊天室中,如沒有進入聊天室就傳送聊天室訊息、設定屬性 |
| 403 | chatroom_muted | 在聊天室中被禁言(details.reason 為 member,details.muted_until 為到期時間,永久為 null),或聊天室開啟了全員禁言(details.reason 為 all) |
| 409 | owner_transfer_required | 需要先轉讓所有者或群主身份,如退出租戶、群主退群 |
| 409 | slot_unavailable | 兩個 Secret 槽位都已佔用,須先吊銷一個;輪換回撥的簽名金鑰時,舊金鑰的寬限期還沒有結束,見輪換金鑰 |
| 409 | last_active_secret | 不能吊銷應用最後一個有效的 Secret |
| 409 | device_limit_exceeded | 登入裝置數已達上限,且應用設定為拒絕新裝置登入 |
| 409 | call_in_progress | 本人已在通話中,不能再發起、接聽或加入:details.reason 為 in_other_call(在另一個通話中,details.call_id 為那個通話)或 joined_on_other_device(已在本人的另一臺裝置上接聽或加入了這個通話) |
| 409 | call_ended | 通話已經結束,不能再接聽、加入、邀請、續期或心跳,details.end_reason、details.ended_at 為結束的原因和時間 |
| 410 | invitation_expired | 邀請已過期、已撤銷或已被接受 |
| 429 | too_many_attempts | 登入失敗次數過多,暫時限制登入 |
客戶端和控制檯介面中,常見的錯誤碼還可能帶以下 details.reason,它們不會由 OpenAPI 返回:
code | details.reason | 說明 |
|---|---|---|
limit_exceeded | app_connection_limit | 建立長連線時,應用的線上連線數已達套餐的併發連線數額度,新的連線被關閉;已經建立的連線不受影響。斷開說明中帶 30 到 60 秒的等待時間,客戶端按它等待後再重新連線 |
limit_exceeded | chatroom_member_limit | 聊天室人數已滿,不能進入 |
limit_exceeded | connection_room_limit | 這條長連線已經在 10 個聊天室中,不能再進入 |
limit_exceeded | call_full、call_member_limit | 群通話人數已滿;群通話累計涉及的成員已達 100 人 |
limit_exceeded | app_concurrent_calls | 應用進行中的通話數已達套餐的併發通話額度,details.limit 為額度,見併發通話額度 |
limit_exceeded | credential_limit、template_limit | 控制檯:應用的推送憑據已有 20 份;通知模板的覆蓋已有 300 條 |
limit_exceeded | endpoint_limit、rps_limit | 控制檯:應用已有 5 個回撥地址;回撥地址的每秒請求數超過了應用的上限,details.max 為上限 |
permission_denied | chatroom_banned | 使用者被這個聊天室封禁,不能進入,details.expires_at 為到期時間,永久為 null |
permission_denied | priority_denied | 只有聊天室的所有者和管理員可以傳送高優先順序的訊息 |
permission_denied | role_required | 需要聊天室的所有者或管理員身份,details.required_role 為需要的身份 |
permission_denied | admin_protected | 聊天室的管理員不能處置其他管理員 |
permission_denied | set_by_higher_role | 禁言或封禁是所有者或服務端設定的,管理員不能修改或解除 |
permission_denied | client_create_disabled | 應用沒有允許客戶端建立聊天室 |
permission_denied | recall_window_expired、recall_denied | 聊天室訊息已超過撤回時限;沒有撤回這條聊天室訊息的許可權 |
permission_denied | attribute_owned | 聊天室屬性由別人設定,普通使用者不能修改或刪除,在設定、刪除屬性的結果中按鍵返回 |
permission_denied | rtc_disabled | 應用沒有開啟音影片:執行策略 rtc_enabled 沒有開啟,或應用的套餐不包含音影片 |
permission_denied | rtc_suspended | 本應用的音影片已被平臺停用,details.suspend_reason 為原因 |
permission_denied | rtc_not_configured | 音影片服務暫不可用 |
permission_denied | not_host、not_in_call、not_joined_device | 不是發起人、群主或群管理員卻結束群通話;不在通話中卻邀請他人;不是在通話中的那臺裝置卻續期媒體憑據 |
permission_denied | media_provider_unsupported | 客戶端不支援當前的媒體服務,請提示使用者升級 App |
permission_denied | report_disabled | 應用關閉了客戶端舉報(執行策略 report_enabled),代使用者舉報不受影響 |
permission_denied | platform_disabled | 控制檯:推送憑據或回撥地址已被平臺停用,只有平臺可以恢復 |
version_conflict | member_state | 本人在通話中的狀態不允許這個操作,如接聽之後又拒絕,details.member_state 為本人當前的成員狀態(從未被邀請為 null) |
invalid_argument | invalid_ext | 進入聊天室或發起通話時的 ext 不符合要求 |
invalid_argument | invalid_target、self_call 等 | 通話操作的引數錯誤,見客戶端需要做什麼 |
invalid_argument | unknown_credential、platform_mismatch 等 | 客戶端登記推送失敗,見客戶端登記推送令牌 |
invalid_argument | url_not_allowed | 客戶端提交的頭像、聊天室封面或附件地址不符合執行策略 media_url_only 的限制;控制檯:回撥地址的 URL 不符合要求,details.rule 指出原因,見地址的要求 |
invalid_argument | unknown_event_type、invalid_filter、invalid_condition | 控制檯:回撥地址訂閱了不認識的事件型別(details.event_type 為這一項);過濾條件不正確;同步回撥的呼叫條件不正確 |
invalid_argument | endpoint_unverified、endpoint_disabled、endpoint_mismatch | 控制檯:回撥地址還沒有透過 URL 驗證;地址已被自動停用,請先恢復;同步回撥繫結的不是本應用的回撥地址。見回撥配置 |
客戶端介面還有按使用者的頻率限制,超出時返回 429 rate_limited,details.reason 為 request_rate(每分鐘或每天的次數)、pair_daily_limit(同一個人每天向同一個人傳送好友申請、向同一個群申請入群的次數)、declined_cooldown(好友申請或入群申請被拒絕後 24 小時內不能再申請;群邀請僅在應用開啟邀請冷卻時,退群或拒絕邀請後 24 小時內不能再次邀請)、group_join_rate(這個群每分鐘入群的人數已滿),傳送訊息時的 user_send_rate、new_conversation_rate、mention_rate、conversation_send_rate、peer_receive_rate,聊天室的 join_rate(每條連線每分鐘進入的次數)、room_join_rate(這個聊天室每秒進入的人數已滿)、attribute_rate(每個使用者每分鐘設定屬性的次數),以及通話操作的 call_rate、pair_call_rate、group_call_rate、invite_rate、signal_rate、token_rate、query_rate(見音視訊通話)。控制檯中測試推送過於頻繁時為 test_rate;回撥地址的 URL 驗證和測試傳送超過每個應用每分鐘 20 次時不帶 details。
服務端代使用者操作時不受其中大部分限制,例如以使用者的身份傳送訊息時不檢查禁言、黑名單和好友關係,見傳送訊息。
錯誤處理建議
按錯誤的型別決定是否重試:
| 錯誤 | 是否重試 | 建議 |
|---|---|---|
429 rate_limited | 是 | 按響應頭 Retry-After 的秒數等待後重試,不要立即重試。持續出現時降低呼叫頻率,見限流與應用狀態 |
500 internal、網路錯誤、超時 | 是 | 用指數退避重試,如依次等待 1 秒、2 秒、4 秒,並加上隨機的抖動,重試幾次仍失敗後告警。寫操作的重試見下文 |
401 unauthenticated | 換取後重試一次 | 重新換取 App Token 後重試一次;仍然失敗,或 details.reason 為 app_deleted、tenant_closed 時停止 |
409 version_conflict | 讀取後再決定 | 重新讀取最新的資料,確認仍需修改後帶上新的 version 再提交 |
410 file_expired、403 file_blocked | 否 | 檔案已過期、已刪除或被遮蔽,重試也不會成功。客戶端提示使用者“檔案已過期”或“檔案已被遮蔽” |
403 tenant_unavailable、403 app_unavailable | 否 | 服務處於暫停或只讀狀態,短時間內重試沒有意義。請告警,並在控制檯檢視租戶和應用的狀態;只讀狀態下查詢仍然可用。details.reason 為 arrears 時請結清欠費,見逾期與欠費 |
403 message_rejected、403 content_rejected,以及 details.reason 為 app_rejected 的 403 permission_denied | 否 | 內容沒有透過內容安全檢查,或被你的同步回撥拒絕,重試同樣的內容也不會成功,請提示使用者修改。details.reason 為 check_timeout(第三方稽核超時)或 callback_unavailable(同步回撥失敗)時可以稍後重試 |
409 limit_exceeded | 否 | 已達數量上限,重試也不會成功。註冊使用者數、群總數、儲存容量、聊天室數等應用級的額度用滿時,請刪除不再需要的資料或更換套餐,見套餐的額度 |
其他 4xx | 否 | 請求本身有問題(引數、許可權或資料的狀態),修正後再提交 |
寫操作的重試要注意冪等。網路超時後,你無法確定上一次請求是否已經執行。查詢可以直接重試;寫操作請按重試與冪等的規則處理:
- 傳送訊息時帶上自己生成的
client_msg_id,超時後用同一個值重試,不會重複傳送; - 建立返回
409 already_exists、刪除返回404 not_found時,可以視為上次已經成功; - 其他寫操作先查詢結果,再決定是否重試。
記錄 request_id。請在日誌中記下每個失敗請求的 request_id,以及請求的時間、方法、路徑和錯誤碼,聯絡技術支援時提供它,可以快速找到這次請求。也可以在請求頭 X-Request-ID 中傳入你自己的追蹤 ID,服務端會原樣使用,便於把你的日誌與我們的排查對應起來:
curl "$IM_API/$ORG/$APP/users/zhangsan" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "X-Request-ID: order-svc-7f3a9c"獨立 RTC 頻道
頻道介面另外使用兩個通用錯誤碼:409 conflict 表示資源或冪等狀態衝突,503 unavailable 表示暫時不可用。它們不代替 already_exists 和 version_conflict。details.reason 的取值和處理方式:
code | details.reason | 怎麼處理 |
|---|---|---|
invalid_argument | invalid_channel_id、invalid_request、invalid_role | 修正引數 |
not_found | channel_not_found、session_not_found | 頻道或會話不存在,或你沒有許可權看到。票據無效時也返回這個,見客戶端票據錯誤 |
permission_denied | channel_banned、rtc_disabled、rtc_suspended | 被封禁或功能沒有開啟,修正後再操作,不要自動重新加入 |
conflict | channel_closed、session_left、join_deadline_exceeded | 停止這次會話並清理 |
conflict | media_resource_busy、joined_on_other_device、session_already_exists | 查詢當前會話:退出原來的會話,或繼續使用它 |
conflict | idempotency_conflict | 同一個加入或操作 ID 用於不同的引數,不能這樣複用 |
already_exists | channel_id_used | 換一個頻道 ID;關閉的頻道 ID 不能再用 |
version_conflict | version_conflict、members_changed | 重新讀取版本;成員列表從第一頁重新查詢 |
limit_exceeded | channel_full、active_media_limit、channel_limit | 等待席位或額度釋放,或調整容量和額度 |
unavailable | media_preparing、media_reclaiming、media_unavailable、admission_unavailable | 按 Retry-After 有限次地重試,保持原來的加入 ID |
unavailable | deployment_config_changed | 服務端例項的配置需要同步,請聯絡平臺處理;換一個加入 ID 也無法繞過 |
- 加入時返回的
503可能帶本人的session_id和join_deadline,重試不會延長首次加入的期限。 - 簽發票據失敗時不要自動重試,見簽發票據。
- 媒體 Token 過期或 HTTP 介面拒絕授權後,即使 LiveKit 的連線還在,也不能繼續參會。
- SDK 在本地沒有媒體能力時報告
unsupported;採集限制和許可權錯誤見各端的頻道指南。
可選文案後設資料
錯誤物件可能帶兩個可選欄位:error.message_key 是穩定的文案鍵,error.message_params 是填入文案的引數,可以用它們按你自己的文案顯示錯誤。
- 不是所有錯誤都有這兩個欄位,沒有時使用
message; - 不要根據
message是不是中文來判斷請求是否成功; code、message、details、request_id照常可用;你的同步回撥給出的拒絕提示原樣返回,不會被翻譯。
