如何在错误处理中实现开闭原则,新增错误类型无需修改核心逻辑?
优化JavaScript错误分发逻辑:新增错误类型无需修改核心代码
问题背景
现有JavaScript错误处理逻辑中,handleClientError和handleServerError分别负责处理客户端与服务端错误,核心的handleError函数通过instanceof判断错误类型来分发处理。但每次新增类似ABCSideError的自定义错误类型时,都得修改handleError里的条件判断逻辑,还要新增对应的处理函数——这种方式每次都要改动核心代码,扩展性极差。
需求目标
新增错误类型时,仅需定义对应的处理函数,完全不用修改handleError这类核心逻辑,同时禁止使用if-else或switch语句做动态判断。
解决方案:用映射表实现错误与处理函数的绑定
核心思路是用Map建立「错误构造函数 -> 对应处理函数」的映射关系,handleError只需根据错误的构造函数从映射表中取出处理函数执行即可,完全不用硬编码判断条件。
1. 定义自定义错误类型
// 基础客户端错误 class ClientError extends Error { constructor(message) { super(message); this.name = 'ClientError'; } } // 基础服务端错误 class ServerError extends Error { constructor(message) { super(message); this.name = 'ServerError'; } } // 新增的ABCSide错误(示例) class ABCSideError extends Error { constructor(message) { super(message); this.name = 'ABCSideError'; } } // 后续新增错误只需添加类似的类定义
2. 编写对应错误处理函数
// 客户端错误处理 function handleClientError(err) { console.error(`[客户端错误] ${err.message}`); // 这里可以加具体的错误处理逻辑,比如上报、提示用户等 } // 服务端错误处理 function handleServerError(err) { console.error(`[服务端错误] ${err.message}`); // 具体处理逻辑:比如重试、记录日志等 } // ABCSide错误处理(新增错误时只需加这个函数) function handleABCSideError(err) { console.error(`[ABCSide错误] ${err.message}`); // 自定义处理逻辑 }
3. 建立错误-处理函数映射表
// 核心映射表:键是错误构造函数,值是对应处理函数 const errorHandlerMap = new Map([ [ClientError, handleClientError], [ServerError, handleServerError], [ABCSideError, handleABCSideError] ]); // 新增错误时,只需要往这个Map里追加一行键值对即可
4. 核心分发函数handleError
function handleError(err) { // 根据错误的构造函数获取处理函数,找不到则用默认处理 const handler = errorHandlerMap.get(err.constructor) || (err => { console.error(`[未知错误] ${err.message}`); }); handler(err); }
方案优势
- 符合开闭原则:新增错误类型时,完全不需要修改核心的
handleError函数,只需要添加错误类、处理函数和映射表条目即可。 - 无硬编码判断:彻底抛弃
if-else/switch,靠构造函数与映射表的绑定实现动态分发,逻辑更清晰,维护成本更低。 - 扩展性极强:后续新增任意多的错误类型,都能快速接入,不会影响原有代码逻辑。
内容的提问来源于stack exchange,提问作者Ahzam Ahmed
相关产品推荐
相关产品推荐

