原生html无法实现错误边界,因其是声明式语言,无运行时捕获能力;必须在custom elements的connectedcallback中手动加try/catch捕获渲染错误,attributechangedcallback不处理初始属性,shadow dom降级需内联样式并清空旧内容。

原生 HTML 标签不能直接实现错误边界
HTML 本身是声明式标记语言,没有运行时错误捕获能力,<div error-boundary> 或 <code>onerror 属性写在自定义标签上完全无效。浏览器解析 HTML 错误(如未闭合标签、错位 <script></script>)会静默修复,不抛 JS 异常,try/catch、window.onerror 都捕不到。所谓“组件级错误边界”,必须靠 JS 主动介入,不是 HTML 能配置出来的。
Custom Elements 中必须手动加 try/catch 的位置
Web Components 是最接近“组件”的原生方案,但 customElements.define() 注册后不会自动拦截内部错误。真正能起作用的只有两个钩子:
-
connectedCallback:所有 DOM 操作、模板注入、fetch、JSON.parse必须包在try {...} catch (e) {...}里;否则错误直接冒泡到window.onerror -
attributeChangedCallback:它**不触发初始属性解析**,<my-card title="x"></my-card>中的title不会进这个回调,所以校验逻辑不能只放这儿 - constructor 里写
this.innerHTML = template是典型翻车点——此时节点还没挂载,错误无法捕获,还可能静默失败
Shadow DOM 渲染出错怎么降级
在 this.shadowRoot.appendChild() 前不做检查,传入 null 或文本节点会抛 TypeError;而 Shadow DOM 内部错误 UI 又不能依赖外部 CSS,容易白屏。稳妥做法是:
- 用内联样式写降级提示:
this.shadowRoot.innerHTML = '<div style="color:red;font-size:12px">渲染失败</div>' - 先清空旧内容:
this.shadowRoot.textContent = '',再 append,避免残留非法节点 - 不要在
catch里调用this.render()或其他可能再次出错的方法 - CSS 加载失败、HTML 结构错位、
<img src="404">这类问题,try/catch也无能为力,得靠link.onerror、img.onerror单独监听
哪些错误根本没法被 JS 捕获
很多你以为能“兜住”的错误,其实 JS 层面根本看不到:
- HTML 解析错误(未闭合标签、非法嵌套)→ 浏览器静默修正,
DOMParser也永远返回Document,不会 throw - CSS 解析失败(如
color: #xyz;)→ 控制台报 warning,但不触发任何事件 -
<iframe></iframe>跨域加载失败 → 受同源策略限制,error事件可能静默不触发 -
document.write()写入非法 HTML → 触发 Parser error 日志,但不是 JS 异常,try/catch无效
真正能做的,是在构建期用 html-validate 检查语法,在运行时对关键节点做 element.children.length 校验,而不是幻想靠一层 try 包住整个组件就能万事大吉。











