Discord.js-Erela.js-Lavalink:检测Lavalink无搜索结果及重试优化
优化Lavalink搜索重试逻辑与无结果判断
首先,你的嵌套try/catch写法确实太冗余了,用循环来实现重试会简洁很多。另外我们得先明确如何判断真的无匹配结果,结合你的描述,分两种核心场景处理:
1. 明确搜索结果的判断逻辑
根据Lavalink常用客户端库(比如erela.js)的特性,search方法的返回结果通常有两种情况:
- 搜索成功时,返回一个包含
tracks数组的对象,数组不为空则代表有匹配曲目 - 无匹配结果时,
tracks会是空数组;如果是网络波动、Lavalink服务临时异常,方法会直接抛出错误
结合你说的“无结果时console.log(searchResults)无输出”,大概率是无匹配时方法抛出了异常,或者返回了null/undefined。我们可以写一个统一的判断函数覆盖所有情况:
// 判断是否无有效搜索结果的工具函数 function hasNoValidResults(results) { return !results || !results.tracks || results.tracks.length === 0; }
2. 用循环实现优雅的重试逻辑
我们用for循环控制最多5次重试,每次尝试后要么成功拿到有效结果,要么继续重试,直到次数耗尽:
let searchResults; const maxRetries = 5; // 最多重试5次 let isSuccess = false; for (let i = 0; i < maxRetries; i++) { try { searchResults = await client.music.search(query, message.author); // 检查是否拿到有效结果 if (!hasNoValidResults(searchResults)) { isSuccess = true; break; // 找到结果,直接跳出循环 } console.log(`第${i+1}次搜索无匹配结果,正在重试...`); } catch (error) { console.log(`第${i+1}次搜索失败,错误信息:${error.message},正在重试...`); } } // 循环结束后处理最终结果 if (!isSuccess) { const musicničnašel = new MessageEmbed() .setTitle("**🎵 GLASBA 🎵**") .setColor(0xFF1E24) .setDescription(`**Nisem našel glasbe na podlagi iskalnega niza:** ${query} **Če si prepričan, da je bila to napaka, poskusi še enkrat!**`) .setThumbnail("https://cdn0.iconfinder.com/data/icons/interface-2-9/34/85-512.png") .setFooter('Za izboljšavo pišite predloge na: Anej#0001'); return message.channel.send(musicničnašel).then(d_msg => {d_msg.delete({ timeout: 10000 })}); } // 到这里说明已拿到有效结果,继续后续逻辑(比如让用户选曲) console.log("搜索成功,返回结果:", searchResults);
3. 关键细节说明
- 重试逻辑更灵活:想修改重试次数只需要改
maxRetries的值,比嵌套try/catch好维护太多 - 结果判断更全面:覆盖了
searchResults为null/undefined、tracks属性不存在、tracks为空数组三种无结果场景 - 调试更清晰:每次重试的状态(无结果/服务异常)都有日志输出,方便排查问题
这样既解决了冗余代码的问题,也能更准确地确认是否真的没有匹配曲目,避免因为临时网络波动误判。
内容的提问来源于stack exchange,提问作者Anej




