关键在于统一异常状态的生成、传递与消费流程:服务端标准化错误结构并序列化为json,ssr注入window.__error_state__,客户端直接解析并按code触发预设处理分支,全程规避时间依赖与类型重建。

关键不在“对齐指纹”,而在于统一异常状态的生成、传递与消费流程。服务器和客户端不是在比对两个独立生成的指纹,而是遵循同一套流程契约,让错误信息从产生到呈现全程可控、可预期。
定义标准化错误数据结构
服务端抛出异常后,不直接透传 Error 实例,而是立即转换为纯 JSON 可序列化的对象:
- 字段必须固定:code(业务码)、message(用户提示)、status(HTTP 状态)、timestamp(服务端逻辑时间戳)、traceId(全链路唯一ID)
- 禁止嵌套函数、Promise、Date 实例或自定义原型方法
- 推荐使用静态工厂方法构造,例如 ErrorPayload.from(e, context),确保每次输出结构一致
控制注水阶段的数据边界
SSR 渲染时,错误数据只能以字符串形式注入 HTML,客户端 hydration 阶段仅能从中读取原始 JSON:
- 服务端将错误 payload 写入 window.__ERROR_STATE__ = JSON.stringify(payload)
- 客户端启动时直接 JSON.parse(window.__ERROR_STATE__),不做 new Error() 或类型重建
- 避免框架自动包装:禁用 React 错误边界对原生 Error 的捕获,改由服务端预埋 error 标记 + 数据
统一错误处理入口与响应逻辑
客户端不靠“反序列化函数”还原行为,而是根据 code 和 context 触发预设的处理分支:
- 定义全局错误映射表,如 { 'AUTH_TOKEN_EXPIRED': showErrorBanner }
- hydration 后检查 __ERROR_STATE__ 是否存在,有则立即 dispatch 对应 action 或调用 handler
- 所有 UI 层错误反馈(Toast、Modal、重定向)均由该统一入口驱动,而非散落在各组件中手动 new Error
规避时间与环境依赖陷阱
不要用 Date.now() 或 System.currentTimeMillis() 生成指纹核心字段:
- timestamp 字段必须来自服务端响应头(如 X-Server-Time)或内联 JSON 中已写死的值
- 指纹标识(如日志 ID 或上报 key)应基于 traceId + code + 哈希后的 stack(若需)生成,而非时间
- 客户端本地时间仅用于界面显示(如“2分钟前”),不参与任何一致性判断或去重逻辑











