#node.js #discord.js
#node.js #discord.js
Вопрос:
В моем раздоре.JS бот, мне нужно иметь возможность обрабатывать все неперехваченные исключения.
Я понимаю, что могу использовать process.on('uncaughtException',. . .'
, но мне нужна возможность отправлять сообщение на канал, где была вызвана ошибка (если ошибка была вызвана командой, конечно), и отправлять инструкции для сообщения об ошибке (у меня уже есть метод сообщения об ошибках, и я знаю, каксделать это, не предоставляя им трассировку стека или другую информацию — это не мой вопрос).
Конечно, я всегда мог бы просто поместить try
оператор в каждую отдельную часть кода, где есть малейшая вероятность ошибки, но это было бы очень запутанно. Конечно, у меня мог бы быть модуль, который выполняет обработку ошибок, но что произойдет, если мне нужно добавить еще один аргумент в обработчик ошибок, который потребует изменения в операторах try ? Мне придется потратить часы на просмотр каждого отдельного файла в боте.
Я понимаю, что мне, вероятно, понадобятся некоторые инструкции try и другие методы обработки ошибок, но мне нужно найти более эффективный способ сделать это, если это возможно.
Редактировать: Да, я уже пробовал использовать оператор 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);
}
}
});
Комментарии:
1. это обработчик команд?
2. Я не уверен, о чем ты спрашиваешь? У моего бота есть обработчик команд, да, если это то, что вы спрашиваете.
3. И приходят ли ошибки из обработчика команд?
4. Обычно, да. Я уже пытался поместить оператор try в обработчик команд, но это не сработало. Он просто действовал так, как будто инструкции try там нет, и выдал необработанное исключение.
5. Вы можете отредактировать это в?
Ответ №1:
Если 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)
}
})()
Комментарии:
1. Я добавил ваш код, но он по-прежнему не работает. Необработанная ошибка приводит к сбою бота, и ничего, относящегося к регистрации ошибок, никогда не срабатывает.
2. «это все еще не работает» — что происходит вместо этого? Еще одна ошибка?
3. Отредактировал его. Извините — я только что понял, что это vauge.
4. что такое необработанная ошибка?
5. Я не могу добавлять новые строки в комментарии. Должен ли я отредактировать это в сообщении?
Ответ №2:
Редактировать: не обращайте на это внимания! Оказалось, что ответ другого человека начал работать без видимой причины. Раньше это не работало, но теперь начало работать.
Это решение НЕ является хорошим вариантом для любого. Как MrMythical, так и узел.В документах JS говорится, что это может вызвать проблемы.
В итоге я добавил прослушиватель необработанных исключений в свой interactionCreate
like this по предложению знакомого по Discord:
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 amp; 0x3 | 0x8);
return v.toString(16);
});
}
Это действительно не лучшее решение, но это то, с чем я сейчас работаю.
Комментарии:
1. Не выходить из процесса при этом событии — плохая идея. Возможно, у вас поврежден node.js процесс
2. Вот почему я сказал, что это не оптимальное решение. Тем не менее, я оставляю это на данный момент, так как ничто другое, похоже, сейчас не работает очень хорошо.