question

Kim Strasser avatar image
Kim Strasser asked

Is it possible to use a cancellation token with PlayFab API calls?

Can a client API call take a cancellation token so that the client can cancel his API call at a later moment?

var cancelsource = new CancellationTokenSource();
var token = cancelsource.Token;

For example:

The player calls PlayFabClientAPI.UpdateUserDataAsync and the API call takes much longer than usual to complete. In this special case, the API call could be canceled automatically with a cancellation token.

Is it possible to use cancelsource.Token with PlayFabClientAPI.UpdateUserDataAsync to cancel the API call if the API call doesn't respond normally?

Or is it not necessary to use a cancellation token in this case? Will result.Error have an error message if a PlayFab call takes too much time to complete?

private static async Task UpdatePlayerCountryData(string country, string city)
{

    var cancelsource = new CancellationTokenSource();
    var token = cancelsource.Token;
 
    var result = await PlayFabClientAPI.UpdateUserDataAsync(new PlayFab.ClientModels.UpdateUserDataRequest()
    {
        Data = new Dictionary<string, string>() {
    {"Country", country},
    {"City", city}
    },
         Permission = PlayFab.ClientModels.UserDataPermission.Public
    });


    if (result.Error != null)
        Console.WriteLine(result.Error.GenerateErrorReport());
    else
        Console.WriteLine("Successfully updated user data");

}
Player Data
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
Citrus Yan avatar image
Citrus Yan answered

No, you cannot use a cancellation token with PlayFab API calls using the CSharpSDK (I suppose this is the one you’re using). Take PlayFabClientAPI.UpdateUserDataAsync for example, if you check the source code here:

https://github.com/PlayFab/CSharpSDK/blob/ed7450c8cf43e1e7f9f47d00849744f4d0a366a6/PlayFabSDK/source/PlayFabClientAPI.cs#L4403

        public static async Task<PlayFabResult<UpdateUserDataResult>> UpdateUserDataAsync(UpdateUserDataRequest request, object customData = null, Dictionary<string, string> extraHeaders = null)
        {
            await new PlayFabUtil.SynchronizationContextRemover();


            var requestContext = request?.AuthenticationContext ?? PlayFabSettings.staticPlayer;
            var requestSettings = PlayFabSettings.staticSettings;
            if (requestContext.ClientSessionTicket == null) throw new PlayFabException(PlayFabExceptionCode.NotLoggedIn, "Must be logged in to call this method");




            var httpResult = await PlayFabHttp.DoPost("/Client/UpdateUserData", request, "X-Authorization", requestContext.ClientSessionTicket, extraHeaders);
            if (httpResult is PlayFabError)
            {
                var error = (PlayFabError)httpResult;
                PlayFabSettings.GlobalErrorHandler?.Invoke(error);
                return new PlayFabResult<UpdateUserDataResult> { Error = error, CustomData = customData };
            }


            var resultRawJson = (string)httpResult;
            var resultData = PluginManager.GetPlugin<ISerializerPlugin>(PluginContract.PlayFab_Serializer).DeserializeObject<PlayFabJsonSuccess<UpdateUserDataResult>>(resultRawJson);
            var result = resultData.data;


            return new PlayFabResult<UpdateUserDataResult> { Result = result, CustomData = customData };
        }

You’ll find that it does not implement the cancelling feature, and, this applies to all other API calls.

Therefore, you should check result.Error to identify issues such as PlayFab call takes too much time to complete, errors in request, etc.

4 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Kim Strasser avatar image Kim Strasser commented ·

Is there a certain error code in result.Error when the call takes very long too complete? Will the error code be the same for all API calls in this situation or does the error code depend on the API call?

I want to know if I can check result.Error for a certain error code if (result.Error != null) because I want to display a certain error message in my game when I get this error code.

0 Likes 0 ·
Citrus Yan avatar image Citrus Yan Kim Strasser commented ·

Calls taking very long to complete should be timeout error throwed as a WebException, and errors returned by PlayFab APIs are listed here:

https://github.com/PlayFab/CSharpSDK/blob/ed7450c8cf43e1e7f9f47d00849744f4d0a366a6/PlayFabSDK/source/PlayFabErrors.cs

0 Likes 0 ·
Kim Strasser avatar image Kim Strasser Citrus Yan commented ·

Will PlayFab automatically return an error in result.Error when a timeout error is thrown as a WebException?

Or is it necessary to create a try/catch block in this case for await PlayFabClientAPI.UpdateUserDataAsync to catch the WebException?

try
{
    var result = await PlayFabClientAPI.UpdateUserDataAsync(new PlayFab.ClientModels.UpdateUserDataRequest()
    {
        Data = new Dictionary<string, string>() {
    {"Country", country},
    {"City", city}
    },
        Permission = PlayFab.ClientModels.UserDataPermission.Public
    });

    if (result.Error != null)
        Console.WriteLine(result.Error.GenerateErrorReport());
    else
        Console.WriteLine("Successfully updated user data");
}
catch (Exception ex)
{
    var message = "Exception message: " + ex.Message;
}
0 Likes 0 ·
Show more comments

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.