html不提供结构化错误序列化能力,需javascript主动捕获并转为可枚举plain object;因error属性默认不可枚举,json.stringify(new error('boom'))返回{};正确做法是用object.getownpropertynames提取所有自有属性再序列化。

HTML 本身不提供“结构化错误序列化”能力,所谓“可恢复错误”必须由 JavaScript 主动捕获、标准化、再序列化为字符串——浏览器原生抛出的 Error 对象跨线程或存储时会丢失堆栈和类型,直接 JSON.stringify(error) 得到空对象 {}。
为什么 JSON.stringify(new Error('boom')) 返回空对象
因为 Error 实例的 message、stack、name 等属性默认不可枚举,JSON.stringify 只遍历可枚举自有属性,结果就是空对象。这不是 bug,是规范行为。
- 验证方式:
console.log(Object.keys(new Error('x')))→ 输出空数组[] - 直接
JSON.stringify({ message: 'x', stack: '...' })是有效的,但你得手动提取 - 若在 Worker 或 postMessage 中传递 error,不处理就等于丢掉全部上下文
如何正确序列化一个可恢复的 structured error
核心是把 error 转成 plain object,并保留关键字段。别依赖 error.toString() ——它合并了 name 和 message,无法单独提取或本地化。
- 最小可用结构:
{ name: error.name, message: error.message, stack: error.stack } - 增强健壮性:用
Object.getOwnPropertyNames(error)遍历所有自有属性(包括不可枚举的),再逐个读取 - 兼容跨域/Worker 场景:避免传
error.constructor或原型链,只取 JSON-safe 字段 - 示例代码:
function serializeError(err) { const obj = {}; Object.getOwnPropertyNames(err).forEach(key => { obj[key] = err[key]; }); return obj;}
反序列化后怎么还原成真正的 Error 实例
单纯 JSON.parse() 得到的是普通 object,不是 Error 构造函数实例,err instanceof Error 为 false,且没有 stack 的自动格式化行为。
- 最简还原:
Object.assign(new Error(), parsedObj)—— 但stack属性在多数引擎中是只读的,赋值无效 - 可靠做法:用构造函数重写,例如:
function deserializeError(obj) { const err = new Error(obj.message || ''); err.name = obj.name || 'Error'; err.stack = obj.stack || ''; return err;} - 注意:
stack字符串只是快照,不能触发重新计算;如需真实堆栈,必须在原始错误发生处捕获
真正容易被忽略的点是:序列化 error 不是为了“看起来像错误”,而是为了在另一端能做 if (err.name === 'NetworkError') 这类判断。所以字段名必须稳定、无歧义,不要用 type 或 kind 替代 name,也不要省略 message —— 它是唯一用户可见的可读信息。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











