Files
WebDrop/packages/core/src/errors.ts
T
2026-10-02 00:59:22 +08:00

65 lines
2.1 KiB
TypeScript

/**
* 错误类型。消息里绝不包含密钥、令牌或明文。
*/
export class WebDropError extends Error {
readonly code: string;
constructor(code: string, message: string) {
super(message);
this.name = new.target.name;
this.code = code;
}
}
/** 接收方校验失败的原因,与 test-vectors 的 expect 字段对应。 */
export type IntegrityReason =
| 'auth_failed' // GCM 认证失败:内容被篡改、头部被改、换了频道或条目
| 'bad_envelope' // 封装格式不合法
| 'wrong_mode' // enc 会话收到没有 ENC 标志的帧,或 raw 会话收到 ENC 帧
| 'bad_padding' // 明文长度字段或填充不合法
| 'bad_meta' // 条目元数据不合法
| 'gap' // 帧序号不连续
| 'item_mismatch' // 同一个流里混入了别的条目的帧
| 'flags_changed' // 同一条目内 SNAPSHOT / GATED 标志不一致
| 'duplicate_mismatch' // 同一 (条目, 序号) 出现了不同内容
| 'frame_after_final' // FINAL 之后又出现了帧
| 'final_conflict' // FINAL 的位置前后矛盾
| 'incomplete'; // 流结束时条目还没有已认证的 FINAL
/** 数据被篡改或不符合协议。接收方应丢弃整个条目。 */
export class IntegrityError extends WebDropError {
readonly reason: IntegrityReason;
constructor(reason: IntegrityReason) {
super('integrity', `完整性校验失败: ${reason}`);
this.reason = reason;
}
}
export class LinkError extends WebDropError {
constructor(message: string) {
super('link', message);
}
}
/** 服务端报告的频道模式与链接不符(降级攻击或链接损坏)。 */
export class ModeMismatchError extends WebDropError {
constructor() {
super('mode_mismatch', '频道模式与链接不一致,已拒绝');
}
}
/** 当前会话没有这个能力(例如成员链接没有所有者令牌)。 */
export class CapabilityError extends WebDropError {
constructor(what: string) {
super('capability', `当前链接不具备 ${what} 权限`);
}
}
export class LimitError extends WebDropError {
constructor(message: string) {
super('limit', message);
}
}