2.6 错误处理
框架不能把错误吞掉,也不该直接抛给用户:它要提供统一的错误处理接口,让用户自己决定忽略、打印还是上报。
一、为什么要统一处理
- 框架错误处理机制的好坏,直接决定了用户应用程序的健壮性,还决定了用户开发时处理错误的心智负担。
- 如果框架内部各调用点自行
try...catch或直接抛出,用户拿不到统一入口,也无法把错误集中上报给监控系统。
二、实现思路:registerErrorHandler + callWithErrorHandling
// utils.js
let handleError = null
export default {
foo(fn) {
callWithErrorHandling(fn)
},
bar(fn) {
callWithErrorHandling(fn)
},
// 用户可以调用该函数注册统一的错误处理函数
registerErrorHandler(fn) {
handleError = fn
}
}
function callWithErrorHandling(fn) {
try {
fn && fn()
} catch (e) {
// 将捕获到的错误传递给用户的错误处理程序
handleError(e)
}
}
用户侧使用:
import utils from './utils.js'
// 注册错误处理程序
utils.registerErrorHandler((e) => {
console.log(e)
})
utils.foo(() => { /* ... */ })
utils.bar(() => { /* ... */ })
- 框架内部凡是会执行用户代码的入口,都统一包一层
callWithErrorHandling; - 捕获后的错误只交给用户注册的处理函数,错误处理能力完全由用户控制:忽略错误、打印日志,或调用上报程序将错误上报给监控系统。
三、Vue.js 中的统一入口
Vue.js 同样提供注册统一错误处理函数的能力:
import App from './App.vue'
const app = createApp(App)
app.config.errorHandler = (err, instance, info) => {
// 错误处理程序
}
有了统一入口,用户只需在一处配置,就能兜住所有组件抛出的错误;框架内部也无需在每个调用点重复写
try...catch。
相关
- 2.5 特性开关:框架向用户暴露的另一种「控制权」。
- 2.7 良好的 TypeScript 类型支持:错误处理之外的另一种开发体验保障。