discord.js斜杠命令机器人fetch错误处理失效,请求失败崩溃如何解决?
问题修复方案
核心问题
- 未捕获fetch请求抛出的reject异常:服务器宕机、超时等网络问题会触发fetch抛出错误,当前代码仅处理了resolve状态的返回,无catch逻辑,导致未捕获异常直接崩溃
- 异步方法漏加await:
fetchGameFile.json()是异步方法,未加await时拿到的是Pending状态的Promise,直接访问属性必然报错 - 斜杠命令3秒超时:Discord斜杠命令默认要求3秒内完成回复,网络请求耗时很容易超出该阈值,超出后交互会被标记为失效,再调用reply就会报10062 Unknown interaction错误
- 无返回结构兜底校验:API返回格式不符合预期时会直接触发读取属性报错
修复代码
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) { // 先延迟回复,将交互有效期延长到15分钟,避免3秒超时失效 await interaction.deferReply(); const targetFileName = interaction.options.getString('file'); try { const imageFile = interaction.options.getSubcommand(); const fetchGameFile = await interaction.client.fetch(`${interaction.client.config.gtaApiServer}/api/v1/gta/sa/${imageFile}?title=${targetFileName}`); if (!fetchGameFile.ok) { return await interaction.editReply('文件服务器暂时不可用,请稍后再试'); } // 加await读取json返回值 const gameFileData = await fetchGameFile.json(); // 兜底校验返回结构是否符合预期 if (!Array.isArray(gameFileData) || !gameFileData[0]) { return await interaction.editReply(`未找到名为 ${targetFileName} 的文件`); } const fileInfo = gameFileData[0]; let hasReplied = false; if (fileInfo.urlDFF) { await interaction.editReply({ files: [fileInfo.urlDFF] }); hasReplied = true; } if (fileInfo.urlTXD) { if (hasReplied) { await interaction.followUp({ files: [fileInfo.urlTXD] }); } else { await interaction.editReply({ files: [fileInfo.urlTXD] }); hasReplied = true; } } if (!hasReplied) { await interaction.editReply(`未找到名为 ${targetFileName} 的文件`); } } catch (err) { // 统一捕获所有错误,包括网络超时、接口报错、Discord交互错误 console.error('fetchtest命令执行出错:', err); // 校验交互状态,避免二次报错 if (interaction.replied || interaction.deferred) { await interaction.editReply('命令执行失败,请稍后再试'); } else { await interaction.reply({ content: '命令执行失败,请稍后再试', ephemeral: true }); } } }, };
内容的提问来源于stack exchange,提问作者Cascavel
相关产品推荐
相关产品推荐

