quick.db调用db.subtract时报错「target is not a number」的问题排查
quick.db调用db.subtract触发「target is not a number」的修复方案
报错核心原因
db.subtract方法要求操作的目标值、参与计算的差值必须为合法数字,否则会触发内置校验抛出报错。结合你提供的代码逻辑,存在两处必然触发报错的问题:
- 定时执行的
updatewater函数内,重新读取数据库值的db.fetch调用没有加await,同步调用拿到的是Promise对象而非实际存储的数值,后续基于非数字对象做大小比较、减法运算会产出无效的NaN结果,传入db.subtract时直接不符合数字要求 - 所有数据库读取结果没有做空值兜底,当对应存储键下无历史数据时,
db.fetch会返回null,参与数值运算时同样会生成非数字的无效结果,操作时会因为找不到可计算的数字目标触发报错
修复后参考代码
补全异步等待、增加空值兜底、计算后做数字合法性校验,避免无效值传入db.subtract:
const db = require('quick.db'); module.exports = { name: 'farmstart', description: 'Gives you your first chicken to start farming with.', execute: async (message, args, Discord) => { let user = message.author async function updatewater() { // 读取值时做转数字处理,空值兜底为0 const chickens = Number(await db.fetch(`chickens_${user.id}`)) || 0; const water = Number(await db.fetch(`water_${user.id}`)) || 0; if (water < chickens) { const waterdif = chickens - water // 仅当计算结果为有效正数时才执行数据库减法操作 if (Number.isFinite(waterdif) && waterdif > 0) { await db.subtract(`chickens_${user.id}`, waterdif) console.log(`took ${waterdif} water from ${user.tag}`) } } // 保持原有的6小时循环计时逻辑 setTimeout(updatewater, 21600000) } // 保持原有的首次延迟5秒触发逻辑 setTimeout(updatewater, 5000) } }
延伸排查方向
如果修改上述逻辑后仍报错,可在调用db.subtract前打印目标键下的实际存储值,排查是否存在被误写入非数字格式内容(比如带单位的字符串、空值)的情况,将异常存储值修正为纯数字即可。
内容的提问来源于stack exchange,提问作者Devalina
相关产品推荐
相关产品推荐

