Search code examples
javascriptnode.jsdiscorddiscord.jsriot-games-api

Why am I not able to catch a Discord.js error in a command handler?


So I'm new to Javascript and trying to making a discord bot. Here is a very small portion that illustrates my problem:

    module.exports = {
    name: "match",
    category: "LOL",
    description: "Give Summoner's Data to User",
    run: async (client, message, args) => {
        var username = `${args}`
        var regionID= "na1"

        pyke.summoner.getBySummonerName(username, regionID).then(data => {
            return pyke.spectator.getCurrentGameInfoBySummoner(`${data.id}`, "na1").then(result => {
                try {
                    console.log(result)
                } catch (err) {
                    console.error(`${args} isn't in game!`)
                }
            })
    })
    }
}

I was expected to see if an error cause, it will send a code to a console. However, I get a UnhandledPromiseRejectionWarning. My question is why can't I catch an error and send a code to the console?

So This is what I try for the command

const property1 = result.participants.summonerName
            const BResult = property1
            let FResult =  JSON.stringify(BResult)
            message.channel.send(FResult)

and when I try, I got an error says that this person isn't in-game. I know it's false because they are in-game.

So I went further and try to do this instead.

const property1 = result.participants[summonerName]
            const BResult = property1
            let FResult =  JSON.stringify(BResult)
            message.channel.send(FResult)

I still get the same result from the last one. I also try to do const property1 = result.summonerName, but it didn't work as well.


Solution

  • Try instead to wrapping the pyke.spectator.getCurrentGameInfoBySummone in a try/catch. This example uses try/catch with the await keyword:

    module.exports = {
      name: "match",
      category: "LOL",
      description: "Give Summoner's Data to User",
      run: async (client, message, args) => {
        const username = `${args}`;
        const regionID = "na1";
    
        return pyke.summoner.getBySummonerName(username, regionID).then((data) => {
            try {
                const result = await pyke.spectator.getCurrentGameInfoBySummoner(`${data.id}`, "na1");
                console.log(result);
            } catch (err) {
                console.error(`${args} isn't in game!`);
            }
        });
      },
    };
    

    Otherwise you can try just using a Promise catch for the error:

    module.exports = {
      name: "match",
      category: "LOL",
      description: "Give Summoner's Data to User",
      run: async (client, message, args) => {
        const username = `${args}`;
        const regionID = "na1";
    
        return pyke.summoner.getBySummonerName(username, regionID).then((data) => {
            return pyke.spectator.getCurrentGameInfoBySummoner(`${data.id}`, "na1")
                .then(result => {
                    console.log(result);
                })
                .catch(err => {
                    console.error(`${args} isn't in game!`)
                }); 
        });
      },
    };
    

    You can use JSON.stringify to stringify an object and you can use a variety of different methods such as destructuring to extract specific properties you only want to return in combination with creating/returning a new object:

    // extract specific properties from `result`
    // This is use ES6 destructuring, but you can use dot notation instead or whatever you prefer
    const { property1, property2, property 3 } = result;
    // return the stringified object only with the properties you need
    const payload = { property1, property2 ,property };
    return JSON.stringify(payload)