BotPress引入Knex后触发split未定义错误致服务崩溃如何解决
错误根因
该错误由BotPress内置的遥测统计模块逻辑缺陷导致:sdk-stats.js在扫描项目代码中引入的第三方SDK方法名做用量统计时,未对扫描到的方法名属性做空值校验,Knex实例导出的特殊属性没有name字段,调用split方法时触发未捕获的类型错误。v12.14.1版本未将此类异步未捕获错误列为致命错误,因此不会触发服务崩溃,高版本调整了异常处理逻辑后会直接终止进程,进而触发重启次数上限报错。
可行解决方案(不影响原有业务逻辑)
方案1:修复BotPress遥测模块源码(推荐)
该方案无需改动业务代码,也不需要关闭使用统计功能:
- 找到BotPress对应目录下的
core/telemetry/stats/sdk-stats.js文件:如果是已打包的分发版本,可使用asar工具解压bp核心包后修改 - 定位到
parseMethods方法中调用split的代码行,在执行split前添加空值校验:- 可以在filter逻辑中新增过滤条件:保留
name属性不为空的项,即添加&& item.name判断 - 也可以直接将调用split的代码改为可选链写法:
item?.name?.split('xxx') || []
- 可以在filter逻辑中新增过滤条件:保留
- 保存修改后重启BotPress服务即可。
方案2:包装Knex实例导出逻辑
该方案无需改动BotPress源码:
将Knex实例的初始化和导出逻辑做一层封装,避免被遥测模块的静态扫描识别到Knex实例,示例代码如下:
// 单独封装为db.js文件 let knexInstance = null function initKnex() { return require('knex')({ client: 'pg', connection: 'postgres://username:password@host:port/dbname', pool: { min: 0, max: 10 }, useNullAsDefault: false, log: { warn(message) { console.log(message) }, error(message) { console.error(message) }, deprecate(message) { console.log(message) }, debug(message) { console.log(message) } } }) } module.exports.getKnex = () => { if (!knexInstance) { knexInstance = initKnex() } return knexInstance }
业务侧使用时调用getKnex()方法获取实例即可,原有Knex的所有功能不受影响。
内容的提问来源于stack exchange,提问作者Abishek Naagendra
相关产品推荐
相关产品推荐

