【问题标题】:Why won't this fetch error handling work?为什么这个 fetch 错误处理不起作用?
【发布时间】:2021-10-29 09:31:07
【问题描述】:

我有一个使用 discord.js 的 Discord 机器人。由于我实现了斜线命令,如果服务器在从中获取文件时关闭,它将使我的机器人崩溃。我已经尝试了很多方法,但我似乎一辈子都无法弄清楚如何正确捕获错误。

这是我的命令代码:

<!-- language: js -->
const { SlashCommandBuilder } = require('@discordjs/builders');

module.exports = {
    data: new SlashCommandBuilder()
        .setName('fetchtest')
        .setDescription('Fetch GTA:SA files.')
        .addSubcommand(gta3Cmd =>
            gta3Cmd
                .setName('gta3')
                .setDescription('Fetch files from gta3.img')
                .addStringOption(option => option.setName('file').setRequired(true).setDescription('File to fetch from database.')))
        .addSubcommand(playerCmd =>
            playerCmd
                .setName('player')
                .setDescription('Fetch files from player.img')
                .addStringOption(option => option.setName('file').setRequired(true).setDescription('File to fetch from database.'))),

    async execute(interaction) {
        let imageFile;
        if (interaction.options.getSubcommand() === 'gta3') {
            imageFile = 'gta3';
        }
        else if (interaction.options.getSubcommand() === 'player') {
            imageFile = 'player';
        }

        await interaction.client.fetch(`${interaction.client.config.gtaApiServer}/api/v1/gta/sa/${imageFile}?title=${interaction.options.getString('file')}`)
            .then((fetchGameFile) => {
                if (fetchGameFile.ok) {
                    const gameFileData = fetchGameFile.json();
                    let hasReturned = false;

                    if (gameFileData[0].urlDFF != undefined) {
                        interaction.reply({
                            files: [
                                gameFileData[0].urlDFF,
                            ],
                        });
                        hasReturned = true;
                    }

                    if (hasReturned === true && gameFileData[0].urlTXD != undefined) {
                        interaction.followUp({
                            files: [
                                gameFileData[0].urlTXD,
                            ],
                        });
                    }

                    else if (hasReturned === false && gameFileData[0].urlTXD != undefined) {
                        interaction.reply({
                            files: [
                                gameFileData[0].urlTXD,
                            ],
                        });
                    }

                    else {
                        interaction.reply(`File with name ${interaction.options.getString('file')} not found.`);
                        return;
                    }
                }
                else {
                    return interaction.reply('Server is down');
                }
            });
    },
};

这会触发以下错误:

FetchError: request to http://serverip/api/v1/gta/sa/gta3?title=fam2 failed, reason: connect ETIMEDOUT serverip
    at ClientRequest.<anonymous> (C:\Projects\klochon\node_modules\node-fetch\lib\index.js:1461:11)
    at ClientRequest.emit (node:events:394:28)
    at Socket.socketErrorListener (node:_http_client:447:9)
    at Socket.emit (node:events:394:28)
    at emitErrorNT (node:internal/streams/destroy:157:8)
    at emitErrorCloseNT (node:internal/streams/destroy:122:3)
    at processTicksAndRejections (node:internal/process/task_queues:83:21) {
  type: 'system',
  errno: 'ETIMEDOUT',
  code: 'ETIMEDOUT'
}

C:\Projects\klochon\node_modules\discord.js\src\rest\RequestHandler.js:298
      throw new DiscordAPIError(data, res.status, request);
            ^

DiscordAPIError: Unknown interaction
    at RequestHandler.execute (C:\Projects\klochon\node_modules\discord.js\src\rest\RequestHandler.js:298:13)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async RequestHandler.push (C:\Projects\klochon\node_modules\discord.js\src\rest\RequestHandler.js:50:14)
    at async CommandInteraction.reply (C:\Projects\klochon\node_modules\discord.js\src\structures\interfaces\InteractionResponses.js:99:5)
    at async Client.<anonymous> (C:\Projects\klochon\index.js:51:3) {
  method: 'post',
  path: '/interactions/881934786988499044/aW50ZXJhY3Rpb246ODgxOTM0Nzg2OTg4NDk5MDQ0OjRvUWMzeHVnQzl2QjlIM2tqRVZpSENmTTlkQ1FWYUE1dHFac1JaTWdTcjE2UWZZaXFKYWk2eXppZkM5cE9GcW5HQUdLNnN4UDZXcU5JR2JCelljQUxDdHNJUktpUzdwRmZzYnRzcVZKNFIzczB6MDRHVXlGYndtb0J0a2RzSDZj/callback',
  code: 10062,
  httpStatus: 404,
  requestData: {
    json: {
      type: 4,
      data: {
        content: 'There was an error while executing this command!',
        tts: false,
        nonce: undefined,
        embeds: undefined,
        components: undefined,
        username: undefined,
        avatar_url: undefined,
        allowed_mentions: undefined,
        flags: 64,
        message_reference: undefined,
        attachments: undefined,
        sticker_ids: undefined
      }
    },
    files: []
  }
}

我已经阅读了有关如何在获取时捕获错误的示例,但似乎没有任何效果。有时它会停止崩溃,但机器人不会回复,或者我不会得到 console.log 响应。我会很感激任何提示,谢谢。

【问题讨论】:

  • 您是否在 fetch 承诺中尝试过 .catch

标签: javascript discord.js node-fetch


【解决方案1】:

您的fetch 可能会返回一个因服务器关闭而被拒绝的 Promise。由于您使用的是await,因此会导致 JavaScript 错误。

如果你想使用 async/await 处理被拒绝的 Promise,那么你需要使用 try/catch 块。

try {
  await fetch(...)
} catch(e) {
  // e is the rejected promise reason, usually an error
}

请参阅MDN's "Promise rejection" 了解更多信息。

【讨论】:

  • 这成功了!不敢相信它是如此简单。这是代码:try { fetchGameFile = await interaction.client.fetch(${interaction.client.config.gtaApiServer}/api/v1/gta/sa/${imageFile}?title=${interaction.options.getString('file')}); } catch(e) { interaction.reply({ content: 'Connection has been refused to the server. It may be down! Try again later ?', ephemeral: true }); console.log('ECONN REFUSED - SERVER IS DOWN'); return;
【解决方案2】:

可能是一种解决方法,并不能解决您的实际“问题”,但您可以在整个命令/获取部分周围放置一个 try-catch 块。

【讨论】:

    猜你喜欢
    • 2016-04-28
    • 1970-01-01
    • 2015-09-22
    • 2020-08-17
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多