js set_error_handler自定义
别在 JS 里翻找 set_error_handler,这些才是你需要用的核心 API
很多刚接触 Node.js 或者从 PHP 转战前端的开发者,习惯性地会在控制台输入 set_error_handler,结果直接报红抛出 ReferenceError。这并非你的代码能力问题,而是语言体系差异造成的常见误解。在 JavaScript 生态中,并没有这个原生函数。真正的全局错误捕获,需要换成另一套思维模式。
浏览器环境与服务器不同,它更强调事件的监听机制。如果你想在页面加载阶段就拦截所有未处理的异常,window.onerror 是最基础的切入点。它可以接收五个参数,涵盖消息、源文件、行号、列号以及具体的 Error 对象。
window.onerror = function(msg, source, lineno, colno, error) {
console.log(`捕获到异常:${msg}`);
// 这里适合做上报操作
return true; // 阻止默认的错误处理弹窗
};
返回 true 是一个关键细节,意味着你告诉浏览器“我已经处理了”,避免控制台再次打印冗余信息。不过,onerror 有个老生常谈的缺点,就是它在某些旧环境下无法获取完整的堆栈信息(Stack Trace),尤其是当资源加载失败时。
这时候就需要引入更现代的 window.addEventListener。通过绑定 'error' 事件,你可以获得更丰富的 ErrorEvent 对象,其中往往包含更准确的定位数据。这种方式的优势在于可以解耦逻辑,不用把一大段处理代码硬塞给全局变量,方便后续扩展多个监听器而不互相干扰。
异步时代的到来让问题变得复杂。Promise 链式调用中的 reject 如果没被 catch 住,并不会触发上述的 onerror。要解决这个问题,必须单独监听 unhandledrejection 事件。这在现代前端框架中尤为重要,因为大量业务逻辑都依赖异步请求。一旦遗漏,后台监控里就会出现一堆莫名其妙的 Promise Rejection 警告,却找不到源头。
window.addEventListener('unhandledrejection', event => {
event.preventDefault();
console.error('未被捕获的 Promise 拒绝:', event.reason);
});
在实际落地监控方案时,切忌只打印 console。生产环境的用户根本看不到控制台日志。你需要将这些错误封装成标准化的 JSON 结构,带上版本号、设备指纹等上下文,通过 fetch 或 image 方式发送到后端的采集服务。同时,注意防抖和节流,避免高频错误瞬间打爆网络带宽,掩盖真实故障。
如果是 Node.js 服务端环境,场景则完全不同。那里对应的是 process.on('uncaughtException')。但这通常是最后的防线,一旦触发,进程往往处于不健康状态,最佳实践是记录完日志后立即重启服务,而不是试图在当前进程中继续运行。
技术选型没有绝对的对错,但名称的混淆会导致开发效率的降低。理解底层机制比死记硬背函数名更重要。把精力花在构建完善的报错收集链路,比纠结一个不存在的函数名更有价值。做好错误治理,用户的体验才会真正顺滑起来。


还没有评论,来说两句吧...