首页 > 解决方案 > Checking for a variable in a JSON

问题描述

client.on("message", message => {
    if (!message.content.startsWith(prefix) || message.author.bot) return;

    const args = message.content.slice(prefix.length).split(/ +/);
    const command = args.shift().toLowerCase();

    if (command === `osu`) {

        if (!args.length) {
            const warn2 = new Discord.MessageEmbed()
                .setTitle(`Eek!`)
                .setDescription(`Please type a username to check!`)
                .setColor('#ffb9f4')
            message.channel.send(warn2);

        } else {
            const userosu = new Discord.MessageEmbed()
            got(`https://osu.ppy.sh/api/get_user?k=API_KEY&u=${args}`).then(response => {
                var response = JSON.parse(response.body)
                console.log(response)

                    if (response.body) {
                        message.channel.send('Invalid User!')
                        return;
                    } else {
                        
                        
                        var num = response[0].accuracy;
                        var n = toFixed(num, 2);

                        var num2 = response[0].level;
                        var n2 = toFixed(num2, 0);

                        var num3 = response[0].pp_raw;
                        var n3 = toFixed(num3, 2);
        

                        userosu.setAuthor(`User info for player ${response[0].username}`, `http://s.ppy.sh/a/${response[0].user_id}`, `https://osu.ppy.sh/u/${response[0].user_id}`)
                        userosu.setDescription(`**» Rank:** #${response[0].pp_rank} (${response[0].country}#${response[0].pp_country_rank}) \n**» Total PP:** ${n3} \n**» Accuracy:** ${n}% \n**» Level:** ${n2} \n**» Play count:** ${response[0].playcount}`)


                        message.channel.send(userosu)
                    }
            });
        }
    }
});

The current part I am focusing on would be

if (!response.body) {
             message.channel.send('Invalid User!')
                        return;
                    } else {


                        var num = response[0].accuracy;
                        var n = toFixed(num, 2);

                        var num2 = response[0].level;
                        var n2 = toFixed(num2, 0);

                        var num3 = response[0].pp_raw;
                        var n3 = toFixed(num3, 2);


                        userosu.setAuthor(`User info for player ${response[0].username}`, `http://s.ppy.sh/a/${response[0].user_id}`, `https://osu.ppy.sh/u/${response[0].user_id}`)
                        userosu.setDescription(`**» Rank:** #${response[0].pp_rank} (${response[0].country}#${response[0].pp_country_rank}) \n**» Total PP:** ${n3} \n**» Accuracy:** ${n}% \n**» Level:** ${n2} \n**» Play count:** ${response[0].playcount}`)


                        message.channel.send(userosu)
                    }
            });

Using the osu! API: https://github.com/ppy/osu-api/wiki, I am trying to return if an invalid username is inputted into the bot. Currently, using a correct user works fine but inputting an invalid username brings back this error: (node:42596) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'accuracy' of undefined which relates to

var num = response[0].accuracy;
var n = toFixed(num, 2);

I'm trying to understand what I have done wrong since i'm not very experienced in this kind of stuff. For reference, inputting a good username would bring back

[
  {
    user_id: '2',
    username: 'peppy',
    join_date: '2007-08-28 03:09:12',
    count300: '657863',
    count100: '118557',
    count50: '25576',
    playcount: '7356',
    ranked_score: '427516167',
    total_score: '1903116877',
    pp_rank: '497537',
    level: '66.0953',
    pp_raw: '829.834',
    accuracy: '97.14646911621094',
    count_rank_ss: '15',
    count_rank_ssh: '0',
    count_rank_s: '70',
    count_rank_sh: '0',
    count_rank_a: '115',
    country: 'AU',
    total_seconds_played: '721608',
    pp_country_rank: '11453',
    events: []
  }
]

While inputting a bad username put return

[]

标签: javascriptnode.jsdiscord.js

解决方案


You have a few options:

1. You could first check if response is an empty array before attempting to get the accuracy value out of it:

if (!Array.isArray(response) || response.length === 0) {
    // error handling
} else {
    var num = response[0].accuracy;
    var n = toFixed(num, 2);
    // ...etc
}

2. You could use the optional chaining operator to first pull items out, with a fallback using the nullish coalescing operator:

var num = response?.[0]?.accuracy ?? 0;
var n = toFixed(num, 2); // will be toFixed(0, 2) if response is empty

3. You could wrap the whole operation for the happy path (in which a response exists) in try...catch and put error handling in the catch:

try {
    var num = response?.[0]?.accuracy ?? 0;
    var n = toFixed(num, 2); // will be toFixed(0, 2) if response is empty
    // etc...
} catch (error) {
    // handle error
    console.log('something went wrong:', error);
}

推荐阅读