You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

开发Discord OsuApi命令遇Discord.js数据类型错误,求解决

Discord.js 参数错误排查与Osu API调用修复

问题描述

开发基于Discord的Osu API相关命令时,运行出现以下错误:

Discord.Js The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined

相关代码如下:

const { member, channel, content, guild } = message
const cache = {}

let data = cache[member.id]

if (!data) {
    const e1 = new ME()
        .setTitle(`Fetching Data Please Wait`)
        .setColor("Random")
        .setTimestamp()
        .setFooter({ text: client.user.username, iconURL: client.user.displayAvatarURL() })
    console.log("Fecting From DataBase")
    const msg = await channel.send({ embeds: [e1] })

    await shi().then(async mongodb => {
        try {
            const result = await us.findOne({ _id: member.id })

            if (!result) {
                const e2 = new ME()
                    .setTitle("Aweeee~")
                    .setColor(config.colors.no)
                    .setDescription("No user found set user using 's!setuser <username or userid>' ")
                    .setTimestamp()
                    .setFooter({ text: client.user.username, iconURL: client.user.displayAvatarURL() })
                await setTimeout(() => {
                    msg.edit({ embeds: [e2] })
                }, 5000);
                return
            }

            cache[member.id] = data = [result.text]

        } catch (err) {
            console.log(err)
            message.channel.send("Something bad happened sorry")
        }
    })

    api.user
        .get(data)
        .then(data => {

            const dataJSON = JSON.stringify(data)
            fs.writeFileSync('user.json', dataJSON)
            const dataBuffer = fs.readFileSync('user.json')
            const stringJSON = dataBuffer.toString()
            const parseDATA = JSON.parse(stringJSON)

            console.log(parseDATA.username)
            channel.send("testing")

        })
}

错误原因分析

  1. 异步流程顺序错误:await shi()仅等待shi()函数完成,但不会等待其then回调内的异步操作(数据库查询、data赋值)。导致调用api.user.get(data)时,data还未被赋值,仍是undefined。
  2. 数据类型错误:将data赋值为数组[result.text],但Osu API的user.get()方法需要的是字符串类型的用户ID或用户名,数组不符合参数要求。
  3. 异常分支未终止后续逻辑:当数据库查询不到用户时,执行return仅退出then回调,后续的API调用代码仍会执行,此时data为undefined,触发错误。
  4. 冗余文件操作:先将数据写入文件再读取解析,完全可以直接处理API返回的对象,无需额外IO操作。

修复方案

关键修改点:

  • 改用await替代then嵌套,确保异步操作顺序执行
  • 修正data赋值类型,直接使用result.text字符串
  • 查询不到用户时,使用return终止整个if (!data)分支的后续代码
  • 移除冗余的文件读写逻辑,直接使用API返回的数据

修复后的代码:

const { member, channel, content, guild } = message
const cache = {}

let data = cache[member.id]

if (!data) {
    const e1 = new ME()
        .setTitle(`Fetching Data Please Wait`)
        .setColor("Random")
        .setTimestamp()
        .setFooter({ text: client.user.username, iconURL: client.user.displayAvatarURL() })
    console.log("Fetching From Database")
    const msg = await channel.send({ embeds: [e1] })

    try {
        // 改用await替代then嵌套,确保流程顺序
        const mongodb = await shi();
        const result = await us.findOne({ _id: member.id })

        if (!result) {
            const e2 = new ME()
                .setTitle("Aweeee~")
                .setColor(config.colors.no)
                .setDescription("No user found set user using 's!setuser <username or userid>' ")
                .setTimestamp()
                .setFooter({ text: client.user.username, iconURL: client.user.displayAvatarURL() })
            // setTimeout无需await,本身不返回Promise
            setTimeout(() => {
                msg.edit({ embeds: [e2] })
            }, 5000);
            // 终止后续代码执行
            return
        }

        // 直接赋值为字符串,而非数组
        cache[member.id] = data = result.text;

        // 确保data赋值完成后再调用API
        const apiData = await api.user.get(data);
        console.log(apiData.username);
        await channel.send("testing");

        // 若需保存到文件,直接写入即可,无需重复读写
        fs.writeFileSync('user.json', JSON.stringify(apiData));

    } catch (err) {
        console.log(err);
        await channel.send("Something bad happened sorry");
    }
}

额外说明

  • 若需要等待setTimeout延迟后再执行后续逻辑,可将其封装为Promise:
    const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
    // 使用示例:
    await delay(5000);
    await msg.edit({ embeds: [e2] });
    
  • 当前cache变量在每次命令执行时都会重新创建,无法实现跨请求缓存,若需要持久化缓存,应将cache定义在函数外部。

内容的提问来源于stack exchange,提问作者Shiko Shintaro Ch.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 07:05:34