/** * @description 把可读的失败原因拼接到错误消息中。 * * 这里尽量保留基础类型与 `Error.message`,避免把复杂对象直接序列化成噪音文本。 */ const internalAppendReasonMessage = (message: string, reason: unknown): string => { if (reason === undefined) { return message } if (reason instanceof Error && reason.message !== "") { return `${message} ${reason.message}` } if ( typeof reason === "string" || typeof reason === "number" || typeof reason === "boolean" || typeof reason === "bigint" || typeof reason === "symbol" ) { return `${message} ${String(reason)}` } return message } /** * @description 表示协调原语等待过程中的中止错误。 */ export class CoordinationAbortError extends Error { /** * @description 触发中止的操作名称。 */ readonly operation: string /** * @description 中止信号携带的原始原因。 */ readonly reason: unknown /** * @description 创建一个表示等待被主动中止的错误。 */ constructor(operation: string, reason: unknown) { super(internalAppendReasonMessage(`${operation} aborted.`, reason)) this.name = "CoordinationAbortError" Object.setPrototypeOf(this, new.target.prototype) this.operation = operation this.reason = reason } } /** * @description 表示协调原语等待过程中的超时错误。 */ export class CoordinationTimeoutError extends Error { /** * @description 发生超时的操作名称。 */ readonly operation: string /** * @description 触发超时时等待的毫秒数。 */ readonly timeout: number /** * @description 创建一个表示等待超时的错误。 */ constructor(operation: string, timeout: number) { super(`${operation} timeout after ${timeout}ms.`) this.name = "CoordinationTimeoutError" Object.setPrototypeOf(this, new.target.prototype) this.operation = operation this.timeout = timeout } } /** * @description 表示栅栏某一代被参与者破坏后的错误。 */ export class BrokenBarrierError extends Error { /** * @description 导致当前栅栏代失效的原始原因。 */ readonly reason: unknown /** * @description 创建一个表示“当前代已被其他参与者破坏”的错误。 */ constructor(reason: unknown) { super( internalAppendReasonMessage("Barrier generation was broken by another participant.", reason), ) this.name = "BrokenBarrierError" Object.setPrototypeOf(this, new.target.prototype) this.reason = reason } }