Search Unity

Resolved HttpException 404 Not Found - GetPlayerScoreAsync()

Discussion in 'Leaderboards' started by Brogan89, Apr 27, 2023.

  1. Brogan89

    Brogan89

    Joined:
    Jul 10, 2014
    Posts:
    244
    I'm using GetPlayerScoreAsync() to get the players score but it's not found. Seems like a bug.

    Code (CSharp):
    1. public async UniTask<LeaderboardEntry> GetMyScore()
    2. {
    3.     var entry = await LeaderboardsService.Instance.GetPlayerScoreAsync(_id);
    4.     return entry;
    5. }
    Error:

    Code (CSharp):
    1. HttpException`1: (404) HTTP/1.1 404 Not Found
    2. Unity.Services.Leaderboards.Internal.Http.ResponseHandler.HandleAsyncResponse (Unity.Services.Leaderboards.Internal.Http.HttpClientResponse response, System.Collections.Generic.Dictionary`2[TKey,TValue] statusCodeToTypeMap) (at Library/PackageCache/com.unity.services.leaderboards@dd8c55d0e488/Runtime/com.unity.services.leaderboards.internal/Http/ResponseHandler.cs:114)
    3. Unity.Services.Leaderboards.Internal.Http.ResponseHandler.HandleAsyncResponse[T] (Unity.Services.Leaderboards.Internal.Http.HttpClientResponse response, System.Collections.Generic.Dictionary`2[TKey,TValue] statusCodeToTypeMap) (at Library/PackageCache/com.unity.services.leaderboards@dd8c55d0e488/Runtime/com.unity.services.leaderboards.internal/Http/ResponseHandler.cs:226)
    4. Unity.Services.Leaderboards.Internal.Apis.Leaderboards.InternalLeaderboardsApiClient.GetLeaderboardPlayerScoreAsync (Unity.Services.Leaderboards.Internal.Leaderboards.GetLeaderboardPlayerScoreRequest request, Unity.Services.Leaderboards.Internal.Configuration operationConfiguration) (at Library/PackageCache/com.unity.services.leaderboards@dd8c55d0e488/Runtime/com.unity.services.leaderboards.internal/Apis/InternalLeaderboardsApi.cs:270)
    5. Unity.Services.Leaderboards.Internal.LeaderboardsServiceInternal+<>c__DisplayClass5_0.<GetPlayerScoreAsync>g__GetPlayerScoreInternal|0 () (at Library/PackageCache/com.unity.services.leaderboards@dd8c55d0e488/Runtime/com.unity.services.leaderboards.internal/LeaderboardsServiceInternal.cs:66)
    6. Unity.Services.Leaderboards.Internal.LeaderboardsServiceInternal.RunWithErrorHandling (System.Func`1[TResult] method) (at Library/PackageCache/com.unity.services.leaderboards@dd8c55d0e488/Runtime/com.unity.services.leaderboards.internal/LeaderboardsServiceInternal.cs:213)
    7. Rethrow as LeaderboardsException: Leaderboard entry could not be found
    8. Unity.Services.Leaderboards.Internal.LeaderboardsServiceInternal.RunWithErrorHandling (System.Func`1[TResult] method) (at Library/PackageCache/com.unity.services.leaderboards@dd8c55d0e488/Runtime/com.unity.services.leaderboards.internal/LeaderboardsServiceInternal.cs:221)
    9. Unity.Services.Leaderboards.Internal.LeaderboardsServiceInternal.GetPlayerScoreAsync (System.String leaderboardId) (at Library/PackageCache/com.unity.services.leaderboards@dd8c55d0e488/Runtime/com.unity.services.leaderboards.internal/LeaderboardsServiceInternal.cs:70)
    10. MRL.MRL_Leaderboard.GetMyScore () (at Assets/_MRL/scripts/services/MRL_Leaderboard.cs:39)
     
  2. EmilF_Unity

    EmilF_Unity

    Unity Technologies

    Joined:
    Jun 10, 2022
    Posts:
    18
    Hi Brogan89, can you confirm that the player has submitted a score to the leaderboard in question? That response is expected when a score has not been submitted yet.
     
    unity_AkGames and IainUnity3D like this.
  3. rbitard

    rbitard

    Joined:
    Jan 11, 2022
    Posts:
    197
    I'm like @Brogan89 too, seems a bit harsh to drop an exception for a "normal" use case, an nullable field or something like that would be way better.
    (I have the same problem too but I had to handle it with try catches :mad:)
     
    Brogan89 likes this.
  4. Brogan89

    Brogan89

    Joined:
    Jul 10, 2014
    Posts:
    244
    Hello yes, the player's entry wasn't in the leaderboard. I'm only showing a top-ten situation plus the player's score (image for reference).

    Its working now though :)

    I ended up just adding a try/catch around it to return null for cases the player isn't on the leaderboard.

    I agree with @rbitard though, it would be good to just return null silently as it should be expected behaviour. Or pass in an optional flag to throw errors if the player is missing. Some people may want to see errors here.


    upload_2023-4-28_9-48-58.png
     
    rbitard likes this.
  5. devingunity

    devingunity

    Unity Technologies

    Joined:
    May 26, 2021
    Posts:
    33
    Thanks both for the feedback - we're re-evaluating our usage patterns around when/when not to throw exceptions, so this is all valuable feedback. To add to EmilF's response above, under the current patterns when using a try-catch, you can check the
    Reason
    field on the exception to determine the cause of the error - in this case for example the
    Reason
    field will contain
    EntryNotFound
    .
     
    Brogan89 and IainUnity3D like this.
  6. Chris_Webb

    Chris_Webb

    Joined:
    Mar 18, 2014
    Posts:
    128
    Its not a big deal, but I was also tripped up a bit with this exact issue, and the general error handling requirements for this package. The SDK client documentation examples don't contain any information about the expected error handling methods, and it couldn't hurt to include that, especially if exceptions are part of the intended usage.
     
  7. Brogan89

    Brogan89

    Joined:
    Jul 10, 2014
    Posts:
    244
    Plus. Its a pretty ugly catch lol.

    This is how I'm handling


    Code (CSharp):
    1.             try
    2.             {
    3.                 var entry = await LeaderboardsService.Instance.GetPlayerScoreAsync(_id).AsUniTask();
    4.                 return entry;
    5.             }
    6.             catch (Exception e) when (e is LeaderboardsException or AggregateException)
    7.             {
    8.                 LeaderboardsException lbe = e switch
    9.                 {
    10.                     AggregateException ae => (LeaderboardsException)ae.InnerExceptions.FirstOrDefault(x => x is LeaderboardsException),
    11.                     LeaderboardsException lb => lb,
    12.                     _ => throw new ArgumentOutOfRangeException(nameof(e), e, $"Exception not of type {nameof(LeaderboardsException)} or {nameof(AggregateException)}")
    13.                 };
    14.  
    15.                 if (lbe == null)
    16.                 {
    17.                     Debug.LogException(new NullReferenceException($"{nameof(LeaderboardsException)} not found"));
    18.                     return null;
    19.                 }
    20.              
    21.                 switch (lbe.Reason)
    22.                 {
    23.                     case LeaderboardsExceptionReason.LeaderboardNotFound:
    24.                     case LeaderboardsExceptionReason.EntryNotFound:
    25.                     case LeaderboardsExceptionReason.VersionNotFound:
    26.                     case LeaderboardsExceptionReason.BucketNotFound:
    27.                     case LeaderboardsExceptionReason.TierNotFound:
    28.                     case LeaderboardsExceptionReason.NotFound:
    29.                         Debug.LogWarning($"[Leaderboards] {lbe.Reason}: {lbe.Message}");
    30.                         break;
    31.                  
    32.                     case LeaderboardsExceptionReason.Unknown:
    33.                     case LeaderboardsExceptionReason.NoInternetConnection:
    34.                     case LeaderboardsExceptionReason.ProjectIdMissing:
    35.                     case LeaderboardsExceptionReason.PlayerIdMissing:
    36.                     case LeaderboardsExceptionReason.AccessTokenMissing:
    37.                     case LeaderboardsExceptionReason.InvalidArgument:
    38.                     case LeaderboardsExceptionReason.LeaderboardNotBucketed:
    39.                     case LeaderboardsExceptionReason.LeaderboardBucketed:
    40.                     case LeaderboardsExceptionReason.LeaderboardNotTiered:
    41.                     case LeaderboardsExceptionReason.Unauthorized:
    42.                     case LeaderboardsExceptionReason.TooManyRequests:
    43.                     case LeaderboardsExceptionReason.ServiceUnavailable:
    44.                     case LeaderboardsExceptionReason.ScoreSubmissionRequired:
    45.                         Debug.LogException(e);
    46.                         break;
    47.                  
    48.                     default:
    49.                         throw new ArgumentOutOfRangeException();
    50.                 }
    51.              
    52.                 return null;
    53.             }
    54.             catch (Exception e)
    55.             {
    56.                 Debug.LogException(e);
    57.                 return null;
    58.             }
     
  8. Mr_Veit

    Mr_Veit

    Joined:
    Mar 6, 2021
    Posts:
    3
    You're a little overthinking the solution to this problem :D

    It's enough to specify "LeaderboardException" instead of "Exception" in catch and that's it).


    Code (CSharp):
    1.         private async Task<LeaderboardEntry> GetPlayerScoreAsync()
    2.         {
    3.             try
    4.             {
    5.                 var entry = await LeaderboardsService.Instance.GetPlayerScoreAsync(_id);
    6.  
    7.                 return entry;
    8.             }
    9.             catch (LeaderboardsException exception)
    10.             {
    11.                 Debug.LogError($"[Unity Leaderboards] {exception.Reason}: {exception.Message}");
    12.  
    13.                 return null;
    14.             }
    15.             catch (Exception e)
    16.             {
    17.                 Debug.LogException(e);
    18.  
    19.                 return null;
    20.             }
    21.         }
     
    IainUnity3D and MohamedBadawy like this.