alexa-games / skills-gameon-sdk-js

The Skills GameOn SDK (Beta) is a Node.js package that makes creating leaderboards and competitions, powered by Amazon GameOn, easier for Alexa Skill developers.
https://skills-gameon-sdk.github.io
Apache License 2.0
19 stars 11 forks source link

Bug: Error getting list of matches for player #11

Closed planadecu closed 5 years ago

planadecu commented 5 years ago

I'm calling the getMatchListForPlayer function like this:

    let matchesObj;
    const matchListForPlayerReq = {
        tournamentId: GAMEON.tournamentId,
        player: alexaPlayer
    };
    try {
        matchesObj = await client.getMatchListForPlayer(matchListForPlayerReq);
    } catch (err){
        console.log('Error getting list of matches for player', matchListForPlayerReq, err)
    }

With the following params:

{ tournamentId: 'd1f772de-xxxx-479a-a607-566f8e6ca39c', player: { score: { score: 1376, rank: 1, ordinalRank: '1st', matchId: '86c3e7cc-xxxx-436f-980d-0cafe9678302' }, profile: { name: 'Seemingly Glamorous Donkey', color: '2a3bc3', avatar: 'http://s3-eu-west-1.amazonaws.com/...../avatar/2429.png' }, sessionApiKey: 'e09c7f65-xxxx-4776-87d1-2a452ac9ec15', sessionId: '2ede5e02-xxxx-43b9-9674-8511afa28c01', sessionExpirationDate: 1565735845384, playerToken: '83b52b53-xxxx-44bd-84ad-b7774c67ecc0', externalPlayerId: '2a9102da-xxxx-43a0-a8d6-7f965eb77050' } }

And I get the following error:

TypeError: Cannot read property 'matches' of undefined at SkillsGameOnApiClient.getMatchListForPlayer (/var/task/node_modules/@alexa-games/skills-gameon-sdk/lib/client/skillsGameOnApiClient.js:108:26) at process._tickCallback (internal/process/next_tick.js:68:7)

Could you please take a look?

Thanks, Jordi PS :)

superkew commented 5 years ago

Hi,

Thanks for logging this issue. I am unable to reproduce your error.

I have obfuscated some of the data in your original post.

Here is the sample code I used in a quick debugging session on VSCode using your original values and it returned an array of matches with one element. Could you check your code and compare to the snippet below?

const SkillsGameOnApiClient = require('@alexa-games/skills-gameon-sdk').SkillsGameOnApiClient;

(async () => {
  const client = new SkillsGameOnApiClient();
  let matchesObj;
  const matchListForPlayerReq = \\ Your request object as shared above;
  try {
    matchesObj = await client.getMatchListForPlayer(matchListForPlayerReq);
    console.log(JSON.stringify(matchesObj.matches));
  } catch (err) {
    console.log('Error getting list of matches for player', matchListForPlayerReq, err)
  }
})();
planadecu commented 5 years ago

Hi,

I can't reproduce it either. I have plenty of logs with this error in Cloudwatch. Maybe it only happens the first time this function is invoked with this params. Is there any possibility that could lead to skillsGameOnApiClient.js:108 return an undefined matches object?

This is the full code that I'm using:

/**
 * Submits score for player. Ensures session has not expired before submission.
 * NOTE: stats can also be submitted in the sdk method, but we are not showcasing that here.
 *
 * @param {Player} alexaPlayer
 * @param {Number} score
 * @param {SkillsGameOnApiClient} [client=defaultClient]
 * @returns {Player}
 */
async function submitScore(alexaPlayer, score, client = defaultClient) {

    await refreshPlayerSession(alexaPlayer);

    let matchesObj;
    const matchListForPlayerReq = {
        tournamentId: GAMEON.tournamentId,
        player: alexaPlayer
    };
    try {
        matchesObj = await client.getMatchListForPlayer(matchListForPlayerReq);
    } catch (err){
        console.log('Error getting list of matches for player', matchListForPlayerReq, err)
    }

    if(!matchesObj || !matchesObj.matches || matchesObj.matches.length == 0) {
        const tournamentForPlayerReq = {
            tournamentId: GAMEON.tournamentId,
            player: alexaPlayer
        };
        try {
            await client.enterTournamentForPlayer(tournamentForPlayerReq);
        } catch (err){
            console.log('Error entering tournament player', tournamentForPlayerReq, err)
        }
    }

    await client.submitScoreForPlayer({
        matchId: GAMEON.matchId,
        submitScoreRequest: { score },
        player: alexaPlayer,
        ensureMatchEntered: true
    });
    alexaPlayer.score = await getPlayerScore(alexaPlayer, defaultClient);
    return alexaPlayer;
}
planadecu commented 5 years ago

I've just reproduced it. It happens just after deleting a user from the Tournament from the UI. The code tries to retrieve the matches but it fails. It would be nice that: submitScoreForPlayer has the ensureTorunamentEntered flag.

superkew commented 5 years ago

I will check the error response that comes from GameOn when the above steps are followed and see if I can reproduce the undefined behavior.

superkew commented 5 years ago

I was able to reproduce the behavior and added some logic to return valid objects when there are no available matches. The impact on your code sample above is that you can remove the two value checks on the response object.

https://github.com/alexa-games/skills-gameon-sdk-js/releases/tag/v0.1.2 https://www.npmjs.com/package/@alexa-games/skills-gameon-sdk