Merge pull request #27180 from bdach/better-submission-failure-messaging

Add better submission failure messaging
This commit is contained in:
Dean Herbert 2024-02-19 21:38:23 +08:00 committed by GitHub
commit c87bc8b597
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 26 additions and 17 deletions

View File

@ -52,7 +52,7 @@ protected override GameplayLeaderboard CreateGameplayLeaderboard() =>
Scores = { BindTarget = LeaderboardScores } Scores = { BindTarget = LeaderboardScores }
}; };
protected override bool HandleTokenRetrievalFailure(Exception exception) => false; protected override bool ShouldExitOnTokenRetrievalFailure(Exception exception) => false;
protected override Task ImportScore(Score score) protected override Task ImportScore(Score score)
{ {

View File

@ -118,7 +118,7 @@ private bool handleTokenRetrieval()
token = r.ID; token = r.ID;
tcs.SetResult(true); tcs.SetResult(true);
}; };
req.Failure += handleTokenFailure; req.Failure += ex => handleTokenFailure(ex, displayNotification: true);
api.Queue(req); api.Queue(req);
@ -128,40 +128,49 @@ private bool handleTokenRetrieval()
return true; return true;
void handleTokenFailure(Exception exception) void handleTokenFailure(Exception exception, bool displayNotification = false)
{ {
tcs.SetResult(false); tcs.SetResult(false);
if (HandleTokenRetrievalFailure(exception)) bool shouldExit = ShouldExitOnTokenRetrievalFailure(exception);
if (displayNotification || shouldExit)
{ {
string whatWillHappen = shouldExit
? "Play in this state is not permitted."
: "Your score will not be submitted.";
if (string.IsNullOrEmpty(exception.Message)) if (string.IsNullOrEmpty(exception.Message))
Logger.Error(exception, "Failed to retrieve a score submission token."); Logger.Error(exception, $"Failed to retrieve a score submission token.\n\n{whatWillHappen}");
else else
{ {
switch (exception.Message) switch (exception.Message)
{ {
case "expired token": case @"missing token header":
Logger.Log("Score submission failed because your system clock is set incorrectly. Please check your system time, date and timezone.", level: LogLevel.Important); case @"invalid client hash":
case @"invalid verification hash":
Logger.Log($"Please ensure that you are using the latest version of the official game releases.\n\n{whatWillHappen}", level: LogLevel.Important);
break;
case @"expired token":
Logger.Log($"Your system clock is set incorrectly. Please check your system time, date and timezone.\n\n{whatWillHappen}", level: LogLevel.Important);
break; break;
default: default:
Logger.Log($"You are not able to submit a score: {exception.Message}", level: LogLevel.Important); Logger.Log($"{whatWillHappen} {exception.Message}", level: LogLevel.Important);
break; break;
} }
} }
}
if (shouldExit)
{
Schedule(() => Schedule(() =>
{ {
ValidForResume = false; ValidForResume = false;
this.Exit(); this.Exit();
}); });
} }
else
{
// Gameplay is allowed to continue, but we still should keep track of the error.
// In the future, this should be visible to the user in some way.
Logger.Log($"Score submission token retrieval failed ({exception.Message})");
}
} }
} }
@ -170,7 +179,7 @@ void handleTokenFailure(Exception exception)
/// </summary> /// </summary>
/// <param name="exception">The error causing the failure.</param> /// <param name="exception">The error causing the failure.</param>
/// <returns>Whether gameplay should be immediately exited as a result. Returning false allows the gameplay session to continue. Defaults to true.</returns> /// <returns>Whether gameplay should be immediately exited as a result. Returning false allows the gameplay session to continue. Defaults to true.</returns>
protected virtual bool HandleTokenRetrievalFailure(Exception exception) => true; protected virtual bool ShouldExitOnTokenRetrievalFailure(Exception exception) => true;
protected override async Task PrepareScoreForResultsAsync(Score score) protected override async Task PrepareScoreForResultsAsync(Score score)
{ {
@ -231,7 +240,7 @@ private void submitFromFailOrQuit()
/// <summary> /// <summary>
/// Construct a request to be used for retrieval of the score token. /// Construct a request to be used for retrieval of the score token.
/// Can return null, at which point <see cref="HandleTokenRetrievalFailure"/> will be fired. /// Can return null, at which point <see cref="ShouldExitOnTokenRetrievalFailure"/> will be fired.
/// </summary> /// </summary>
[CanBeNull] [CanBeNull]
protected abstract APIRequest<APIScoreToken> CreateTokenRequest(); protected abstract APIRequest<APIScoreToken> CreateTokenRequest();

View File

@ -61,7 +61,7 @@ public TestPlayer(bool allowPause = true, bool showResults = true, bool pauseOnF
PauseOnFocusLost = pauseOnFocusLost; PauseOnFocusLost = pauseOnFocusLost;
} }
protected override bool HandleTokenRetrievalFailure(Exception exception) => false; protected override bool ShouldExitOnTokenRetrievalFailure(Exception exception) => false;
protected override APIRequest<APIScoreToken> CreateTokenRequest() protected override APIRequest<APIScoreToken> CreateTokenRequest()
{ {