Discord Bot抓取Reddit梗图报Cannot read property 'send' of undefined如何解决
问题修复方案
报错根因
你的报错核心由两个问题触发:
- 递归调用
execute方法时参数传参错位:方法定义的入参顺序是client, message, cmd, args, Discord,但你递归调用时仅传了message, args, Discord三个参数,导致方法内的message变量被赋值为你传入的args,最终为undefined,调用message.channel.send时直接抛出Cannot read property 'send' of undefined错误 - 异常捕获范围不完整:你仅把发送Embed的逻辑放在了try catch块中,前置的Reddit资源请求、URL格式校验、递归调用逻辑都在捕获范围外,出错后无法被catch到,就会抛出未处理的拒绝异常
修复点
- 修正递归调用的参数顺序,确保和方法定义的入参顺序一致
- 新增URL有效性前置校验,避免URL为
undefined时调用endsWith方法报错 - 扩大try catch覆盖范围,将所有异步逻辑都纳入异常捕获
- 新增重试次数上限,避免连续拿到非图片格式的资源时触发无限递归,导致栈溢出
- 优化随机索引生成逻辑,避免生成负数索引
修复后代码
const randomPuppy = require('random-puppy'); const snekfetch = require('snekfetch'); const { MessageEmbed } = require('discord.js') module.exports ={ name: 'meme', description: "generates memes", // 新增retryTimes参数,默认重试次数为3 async execute(client, message, cmd, args, Discord, retryTimes = 3){ // 所有逻辑放入try catch块 try { let reddit = [ "meme", "AnimeFunny", "animememes", "dankmemes", "dankmeme", "wholesomememes", "meirl", "me_irl", "2meirl4meirl", "AdviceAnimals" ] // 优化随机数生成逻辑,直接生成合法索引,无需额外判断负数 let random = Math.floor(Math.random() * reddit.length); let subreddit = reddit[random]; console.log(`Chose ${subreddit} since random was ${random}`) const url = await randomPuppy(subreddit).catch(() => {}); console.log(`URL is ${url}`) // 先判断url存在,再判断格式;如果重试次数耗尽就抛错 if (!url || (!url.endsWith('.png') && !url.endsWith('.jpg'))) { if(retryTimes <= 0) throw new Error('多次重试未获取到有效图片资源') // 修正参数传递,带上所有入参,重试次数减1 return this.execute(client, message, cmd, args, Discord, retryTimes - 1); } const res = await snekfetch.get(url).catch(() => {}); console.log(`RES is ${res}`) if(!res) throw new Error('资源请求失败') const memeEmbed = new MessageEmbed() .setColor('RANDOM') .setTitle(`Meme From /r/${subreddit}`) .setImage(`${url}`) .setTimestamp() .setFooter(`${url}`) await message.channel.send({ embeds: [memeEmbed] }).catch(err => { console.error(err); }); } catch (err) { console.error(err) // 发错误消息前用可选链判断对象存在,避免二次报错 message?.channel?.send(`An error occured whilst attempting to retrieve a meme, Please try again`) } } }
内容的提问来源于stack exchange,提问作者NaturalTwitch
相关产品推荐
相关产品推荐

