在Discord.JS机器人中进行错误处理的最佳方法



在我的Discord.JS bot中,我需要能够处理所有未捕获的异常。

我知道我可以使用process.on('uncaughtException',. . .',但我需要能够向触发错误的通道发送消息(当然,如果错误是由命令触发的(,并发送报告错误的指令(我已经找到了错误报告方法,我知道如何在不给他们堆栈跟踪或其他信息的情况下做到这一点——这不是我的问题(。

当然,我总是可以在代码的每一个部分都放一个try语句,这是最有可能出错的地方,但这会让变得非常混乱。当然,我可以有一个模块来处理错误,但如果我需要向错误处理程序添加另一个参数,这将需要更改try语句,会发生什么?我将不得不花几个小时浏览机器人中的每一个文件。

我知道我可能需要一些try语句和其他错误处理方法,但如果可能的话,我需要找到一种更有效的方法来做到这一点。

Edit:是的,我已经尝试过在命令处理程序中使用try-catch语句。它什么也没做。代码:

const {bot} = require('../index');
const { logError } = require("./utils/ErrorHandling.js");
bot.on("interactionCreate", async interaction => {
if (!interaction.isCommand()) return;
let cmd = interaction.commandName;
if (bot.commands.has(cmd)) {
command = bot.commands.get(cmd);
} else {
command = bot.commands.get(bot.aliases.get(cmd));
}
try {
if (command) command.run(bot, interaction); 
} catch (e) {
logError(e, interaction.channel);
}
});

错误处理模块:

const { errorLoggingWebhook, supportServer } = require("../config.json")
const fetch = require("node-fetch");
module.exports = {
"logError": (error, discordChannel) => {
var errorID = createUUID();
var params = {
username: "Aspectfully Error Logging",
content: `**${errorID}**:
```
${error}
````,
}
fetch(errorLoggingWebhook, {
method: "POST",
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify(params)
}).then(res => {
console.log(res);
}) 
return discordChannel.send(`An error occured while running that command. 

If this continues to occur, please join our [support server](${supportServer}) and tell them an error is occuring.
Also, give them the error ID `${errorID}`.`)
}
}

这是一个发生的错误。我知道有一个简单的解决方案可以防止它发生,但我只是还没有实现它。通过这种方式,我可以测试错误处理功能。

(错误是因为我故意试图使用维基百科API处理维基百科上不存在的页面,就好像它确实存在一样,因此试图读取不存在的值(

C:UsersbekfeOneDriveDocumentsAspectfullycodecommandswikipedia.js:36
wikiParseContents = wikiParse(Object.values(Object.values(JSON.parse(body))[0].text)[0], `https://en.wikipedia.org/wiki/${encodeURI(suffix)}`);
^
TypeError: Cannot convert undefined or null to object
at Function.values (<anonymous>)
at C:UsersbekfeOneDriveDocumentsAspectfullycodecommandswikipedia.js:36:42
at processTicksAndRejections (node:internal/process/task_queues:96:5)

我不是在问如何解决这个特定的错误。我已经知道如何解决它了。问题是错误处理程序没有把它当作错误来处理——我的问题是解决这个特定的错误。

我也尝试过用这种方式执行await函数,但我得到了相同的结果:

const {bot} = require('../index');
const { logError } = require("../utils/ErrorHandling.js");
bot.on("interactionCreate", async interaction => {
if (!interaction.isCommand()) return;
let cmd = interaction.commandName;
if (bot.commands.has(cmd)) {
command = bot.commands.get(cmd);
} else {
command = bot.commands.get(bot.aliases.get(cmd));
}
if (command) {
try {
await command.run(bot, interaction); 
} catch (e) {
logError(e, interaction.channel);
}
}  
});

如果command.run是异步函数,则需要await来捕获错误

try {
if (command) await command.run(bot, interaction); 
} catch (e) {
logError(e, interaction.channel);
}

点击此处查看其工作原理:

async function toThrow() {
throw new Error("Test")
}
try {
toThrow() //check your developer console as it doesn't show here
} catch (err) {
console.log("An error occurred" + err)
}

async function toThrow() {
throw new Error("Test")
}
(async () => {
try {
await toThrow()
} catch (err) {
console.log("An error occurred: " + err)
}
})()

编辑:永远不要这样!另一个人的回答被证明是无缘无故地开始工作。它早些时候不起作用,但已经开始起作用了。

这个解决方案对任何人来说都不是一个好的选择。正如MrMythical和Node.JS文档所说,它可能会引起问题。


根据Discord:上一位熟人的建议,我最终在我的interactionCreate中添加了未处理的异常侦听器,如下所示

process.on("uncaughtException", (e) => {
logError(e, interaction.channel)
});

我还意识到我忘了把createUUID函数放回ErrorHandling.js文件中,所以我把它加回来了(信用(:

createUUID = () => {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}

这确实不是最好的解决方案,但这正是我现在要做的。

最新更新