/** 全局请求错误提示容器(任务 13):框架无关的订阅式错误总线。 */ export interface GlobalErrorItem { id: number message: string } export const GLOBAL_ERROR_LIMIT = 3 export const GLOBAL_ERROR_FALLBACK = '请求失败,请稍后重试' /** 把任意负载归一化为可展示文案。 */ export function normalizeErrorMessage(message: unknown): string { if (message instanceof Error) return message.message.trim() || GLOBAL_ERROR_FALLBACK if (typeof message === 'string') return message.trim() || GLOBAL_ERROR_FALLBACK return GLOBAL_ERROR_FALLBACK } type Listener = (items: GlobalErrorItem[]) => void let items: GlobalErrorItem[] = [] let nextId = 1 const listeners = new Set() function emit(): void { for (const listener of listeners) listener(items.slice()) } /** 订阅错误流,返回取消订阅函数(组件卸载时必须调用以防泄漏)。 */ export function subscribeGlobalError(listener: Listener): () => void { listeners.add(listener) listener(items.slice()) return () => { listeners.delete(listener) } } /** 通知一条全局请求错误;超出上限丢弃最旧,保证不堆积。 */ export function notifyGlobalError(message: unknown): void { items = [...items, { id: nextId++, message: normalizeErrorMessage(message) }].slice(-GLOBAL_ERROR_LIMIT) emit() } /** 按 id 关闭单条。 */ export function dismissGlobalError(id: number): void { items = items.filter((item) => item.id !== id) emit() } export function clearGlobalErrors(): void { items = [] emit() } export function snapshotGlobalErrors(): GlobalErrorItem[] { return items.slice() }