SPECIFICATION
第 9 章 錯誤處理
9.1 錯誤處理模型
DTP 實作 必須 遵循「偵測-通知-恢復」三階段錯誤處理模型:
- 偵測:辨識異常情況。
- 通知:向對端或上層傳送錯誤資訊。
- 恢復:根據錯誤類型採取恢復措施。
實作 不得 在偵測到錯誤時靜默丟棄訊框而不通知。
9.2 錯誤碼體系
DTP 必須 使用以下錯誤碼體系。錯誤碼 必須 是非負整數,按功能模組劃分為八個範圍:
| 範圍 | 類別 | 處理策略 |
|---|---|---|
| 1xxx | 訊框處理錯誤 | 丟棄訊框 + 通知傳送方 |
| 2xxx | 加密錯誤 | 丟棄訊框 + 通知傳送方 + 可能觸發金鑰重協商 |
| 3xxx | 約定錯誤 | 丟棄 Fragment + 通知傳送方 + 可能觸發重新協商 |
| 4xxx | DAG 錯誤 | 拒絕 Fragment + 通知傳送方 或 快取等待 |
| 5xxx | 會話錯誤 | 嘗試恢復會話 + 失敗時關閉並通知上層 |
| 6xxx | 續傳錯誤 | 暫停傳送 + 通知上層應用 |
| 7xxx | 版本錯誤 | 傳送版本不相容通知 + 嘗試降級處理 |
| 8xxx | 權限錯誤 | 拒絕操作 + 通知請求方 |
9.3 錯誤碼定義
實作 必須 使用以下規範化的錯誤碼定義。不得 使用未列出的錯誤碼。如需擴充,必須 在本規範的後續版本中定義。
9.3.1 訊框處理錯誤(1xxx)
| 錯誤碼 | 名稱 | 觸發條件 |
|---|---|---|
| 1001 | FRAME_DESERIALIZATION_FAILED | 接收到的二進位資料無法反序列化為 LogicalFrame |
| 1002 | FRAME_INVALID_FORMAT | LogicalFrame 結構無效或缺少必需欄位 |
9.3.2 加密錯誤(2xxx)
| 錯誤碼 | 名稱 | 觸發條件 |
|---|---|---|
| 2001 | DECRYPTION_FAILED | Payload 解密失敗(錯誤金鑰或資料損壞) |
| 2002 | KEY_NOT_READY | CAP 金鑰交換尚未完成,拒絕資料傳輸 |
9.3.3 約定錯誤(3xxx)
| 錯誤碼 | 名稱 | 觸發條件 |
|---|---|---|
| 3001 | AGREEMENT_NOT_FOUND | Fragment 引用了未知 Agreement_ID |
| 3002 | AGREEMENT_EXPIRED | 引用的約定已過期(超過 validityPeriod) |
| 3003 | AGREEMENT_NEGOTIATION_FAILED | 協商無法完成(逾時、對端拒絕重協商等) |
9.3.4 DAG 錯誤(4xxx)
| 錯誤碼 | 名稱 | 觸發條件 |
|---|---|---|
| 4001 | DAG_CYCLE_DETECTED | 加入 Fragment 會形成 DAG 環路 |
| 4002 | DAG_DEPENDENCY_UNRESOLVED | Fragment 依賴未在快取逾時內解析 |
9.3.5 會話錯誤(5xxx)
| 錯誤碼 | 名稱 | 觸發條件 |
|---|---|---|
| 5001 | SESSION_NOT_FOUND | 引用的 Session_ID 不存在 |
| 5002 | SESSION_TIMEOUT | 會話因不活動逾時 |
| 5003 | SESSION_RESTORE_FAILED | 重新連線後會話恢復失敗 |
9.3.6 續傳錯誤(6xxx)
| 錯誤碼 | 名稱 | 觸發條件 |
|---|---|---|
| 6001 | BUFFER_FULL | 傳送方未確認 Fragment 快取達到容量上限 |
| 6002 | RETRANSMISSION_TIMEOUT | Fragment 重傳逾時未收到確認(重傳次數耗盡) |
9.3.7 版本錯誤(7xxx)
| 錯誤碼 | 名稱 | 觸發條件 |
|---|---|---|
| 7001 | VERSION_INCOMPATIBLE | 接收訊框的協定版本號高於自身支援版本 |
9.3.8 權限錯誤(8xxx)
| 錯誤碼 | 名稱 | 觸發條件 |
|---|---|---|
| 8001 | PERMISSION_DENIED | 當前角色不允許執行該操作 |
| 8002 | OBSERVER_WRITE_DENIED | 旁觀者嘗試寫入操作(旁觀者唯讀) |
9.4 錯誤唯一性
實作 必須 保證錯誤碼的唯一性:
- 每個錯誤碼 必須 對應唯一的錯誤類型。
- 不同錯誤類型 不得 共用同一錯誤碼。
- 實作 不得 重新定義本規範已分配的錯誤碼。
9.5 錯誤通知機制
9.5.1 ErrorNotificationFrame
錯誤通知 必須 透過 ControlFrame 傳遞,定義如下:
interface ErrorNotificationFrame {
frameType: "control";
controlType: "error_notification";
errorCode: DTPErrorCode;
errorMessage: string;
relatedFrameId?: FragmentID;
relatedAgreementId?: AgreementID;
details?: Record<string, unknown>;
}
| 欄位 | 規範性要求 |
|---|---|
frameType | 必須 為 "control" |
controlType | 必須 為 "error_notification" |
errorCode | 必須 為 9.3 節定義的錯誤碼之一 |
errorMessage | 必須 為人類可讀的錯誤描述。應 使用對端可理解的語言 |
relatedFrameId | 可選。當錯誤由特定訊框觸發時 必須 包含該訊框的 fragmentId |
relatedAgreementId | 可選。當錯誤與特定約定相關時 必須 包含 Agreement_ID |
details | 可選。可 包含偵錯用的額外資訊 |
9.5.2 錯誤通知傳輸
ErrorNotificationFrame 必須 透過常規 LogicalFrame 通道傳輸,必須 加密 Payload。
如錯誤本身導致無法加密(例如 KEY_NOT_READY 錯誤),實作 可 透過實作定義的頻外通道返回錯誤,但 不得 在加密通道中以明文傳送錯誤。
9.6 關鍵錯誤處理流程
9.6.1 反序列化失敗(1001)
接收到的 LogicalFrame 無法反序列化時,接收方 必須:
- 丟棄該訊框。
- 傳送
FRAME_DESERIALIZATION_FAILED錯誤通知。 - 不得 因反序列化失敗而關閉會話。
9.6.2 解密失敗(2001)
接收到的 Payload 無法解密時,接收方 必須:
- 丟棄該訊框。
- 傳送
DECRYPTION_FAILED錯誤通知。 - 計數連續解密失敗次數。
- 如連續失敗超過閾值(推薦 3 次),應 觸發 CAP 重新金鑰交換。
9.6.3 DAG 環路偵測(4001)
偵測到 DAG 環路時:
- 接收方 必須 拒絕該 Fragment。
- 必須 返回
DAG_CYCLE_DETECTED錯誤。 - 不得 將 Fragment 加入 DAG。
- 不得 影響已存在 Fragment 的狀態。
9.6.4 未知約定(3001)
Fragment 引用了未知 Agreement_ID 時:
- 接收方 必須 丟棄 Fragment。
- 返回
AGREEMENT_NOT_FOUND錯誤。 - 可 觸發重新協商(實作定義)。
9.6.5 金鑰未就緒(2002)
CAP 金鑰交換尚未完成時嘗試傳送資料:
- DTP_Engine 必須 拒絕傳送。
- 必須 返回
KEY_NOT_READY錯誤給上層呼叫方。 - 不得 在通訊通道中以明文形式回應。
9.6.6 快取已滿(6001)
未確認 Fragment 快取達到上限時:
- 傳送方 必須 暫停傳送新 Fragment。
- 傳送
BUFFER_FULL通知給上層應用。 - 在確認釋放快取空間後恢復傳送。
- 不得 丟棄已快取的 Fragment。
9.6.7 重傳逾時(6002)
Fragment 重傳次數耗盡時:
- 傳送方 必須 通知上層應用
RETRANSMISSION_TIMEOUT錯誤。 - 應 觸發會話暫停或終止。
- 不得 無限重傳。
9.6.8 版本不相容(7001)
接收到協定版本不相容的訊框時(詳見第 10 章):
- 接收方 必須 不處理該訊框。
- 必須 返回
VERSION_INCOMPATIBLE錯誤。 - 必須 在錯誤的
details欄位中包含自身支援的最高版本號。
9.6.9 權限拒絕(8001、8002)
非法的角色操作時:
- DTP_Engine 必須 拒絕該操作。
- 旁觀者寫入操作 必須 返回
OBSERVER_WRITE_DENIED(8002)。 - 其他權限拒絕 必須 返回
PERMISSION_DENIED(8001)。
9.7 錯誤恢復策略
實作 必須 按錯誤類型採取相應恢復策略:
| 錯誤類別 | 恢復策略 |
|---|---|
| 1xxx 訊框處理 | 丟棄訊框,記錄日誌,繼續接收後續訊框 |
| 2xxx 加密 | 單次失敗丟棄訊框,連續失敗觸發金鑰重協商 |
| 3xxx 約定 | 丟棄 Fragment,可能觸發重新協商 |
| 4xxx DAG | 環路:拒絕;未解析:快取等待 |
| 5xxx 會話 | 嘗試恢復會話;失敗則關閉 |
| 6xxx 續傳 | 暫停傳送,等待對端回應或上層介入 |
| 7xxx 版本 | 傳送版本通知;嘗試降級處理 |
| 8xxx 權限 | 拒絕操作,不得 自動重試 |
實作 不得 在權限錯誤(8xxx)發生時自動重試相同操作。
