Search Unity

  1. We are migrating the Unity Forums to Unity Discussions by the end of July. Read our announcement for more information and let us know if you have any questions.
    Dismiss Notice
  2. Dismiss Notice

Bug Cloud Code Module doesn't work with Cloud Save

Discussion in 'Cloud Code' started by ANLevant, Apr 8, 2024.

  1. ANLevant


    Jun 10, 2014
    Hey there.

    I'm trying to implement an automated tournament system for my game, but Cloud code is just behaving in very whack ways when I try to generate brackets once players have registered the tournament.

    This is my Cloud Code Endpoint:

    Code (CSharp):
    1. [CloudCodeFunction("StartTournament")]
    2.     public async Task<TournamentDTO> StartTournament(IExecutionContext context, IGameApiClient gameApiClient, string code)
    3.     {
    4.         _logger.LogInformation("Starting tournament: "+ code);
    5.         TournamentDTO tournamentDto = await GetTournamentByCode(context, gameApiClient, code);
    6.         _logger.LogTrace("Here");
    7.         tournamentDto.State = TournamentDTO.TournamentState.ONGOING;
    9.         if (tournamentDto.TournamentType != TournamentDTO.TournamentMode.GOLDEN_BOOT)
    10.         {
    11.             if (tournamentDto.TournamentType != TournamentDTO.TournamentMode.CUSTOM)
    12.             {
    13.                 _logger.LogDebug("Generating brackets: "+ code);
    14.                 tournamentDto.Brackets.Children = GenerateBrackets(tournamentDto);
    15.             }
    16.         }
    18.         tournamentDto.Brackets.Start(_logger, tournamentDto);
    20.         return UpdateTournament(context, gameApiClient, tournamentDto);
    21.     }
    23. private async Task<TournamentDTO> GetTournamentByCode(IExecutionContext context, IGameApiClient gameApiClient, string code)
    24. {
    25.     _logger.LogTrace("GetTournamentByCode");
    26.     ApiResponse<GetItemsResponse> apiResponse = await gameApiClient.CloudSaveData.GetCustomItemsAsync(context, context.ServiceToken, context.ProjectId, "Tournament"+code);
    27.     GetItemsResponse getItemsResponse = apiResponse.Data;
    28.     TournamentDTO tournamentDto = JsonConvert.DeserializeObject<TournamentDTO>(getItemsResponse.Results[0].Value.ToString());
    29.     _logger.LogDebug("Tournament Found: "+ LogifyTouranamentDto(tournamentDto));
    30.     return tournamentDto;
    31. }
    It prints the first log (Starting Tournameng + code), but then I get an error 500 when calling GetTournamentByCode without reaching any of the logs inside the method. Mind you, I'm calling this method inside other ClodeCode functions (create tournaments and addPlayers) and it works perfectly, it is only on this very specific method that it fails, although I'm treating the data the same way in those three methods. the stack trace really says nothing, in fact, if anything, it's even more misleading:

    Code (CSharp):
    1. HttpException`1: (500) HTTP/1.1 500 Internal Server Error
    2.   at Unity.Services.CloudCode.Internal.Http.ResponseHandler.HandleAsyncResponse (Unity.Services.CloudCode.Internal.Http.HttpClientResponse response, System.Collections.Generic.Dictionary`2[TKey,TValue] statusCodeToTypeMap) [0x00089] in .\Library\PackageCache\\Runtime\\Http\ResponseHandler.cs:122
    3.   at Unity.Services.CloudCode.Internal.Http.ResponseHandler.HandleAsyncResponse[T] (Unity.Services.CloudCode.Internal.Http.HttpClientResponse response, System.Collections.Generic.Dictionary`2[TKey,TValue] statusCodeToTypeMap) [0x00001] in .\Library\PackageCache\\Runtime\\Http\ResponseHandler.cs:226
    4.   at Unity.Services.CloudCode.Internal.Apis.CloudCode.CloudCodeApiClient.RunModuleAsync (Unity.Services.CloudCode.Internal.CloudCode.RunModuleRequest request, Unity.Services.CloudCode.Internal.Configuration operationConfiguration) [0x001fd] in .\Library\PackageCache\\Runtime\\Apis\CloudCodeApi.cs:137
    5.   at Unity.Services.CloudCode.CloudCodeInternal.GetModuleResponseAsync (System.String module, System.String function, System.Collections.Generic.Dictionary`2[TKey,TValue] args) [0x00082] in .\Library\PackageCache\\Runtime\CloudCode.cs:243
    6.   at Unity.Services.CloudCode.CloudCodeInternal.GetRunModuleScriptResponse (System.String module, System.String function, System.Collections.Generic.Dictionary`2[TKey,TValue] args) [0x00047] in .\Library\PackageCache\\Runtime\CloudCode.cs:137
    7. Rethrow as CloudCodeException: ServiceUnavailable
    8. (500) HTTP/1.1 500 Internal Server Error
    9. Error
    10. An unknown server error occurred
    The Cloud Code Log console only shows the logs that I added, and shows nothign about the error at hand, I extracted these logs from my Player.log

    I've tried debugging this code in the most ridiculous way possible (moving the _logger.LogTrace("Here"); line by line and even inside the utility method to see what's even going on). But the result is always the same. _logger.LogTrace("Here"); and _logger.LogTrace("GetTournamentByCode"); are never called. I also tried reviewing the quotas for CloudSave API andI'm not exceeding the 600 calls per minute that it allows for these endpoints.

    Now if I remove the variable assignation on line 5, and leave the line just as
    await GetTournamentByCode(context, gameApiClient, code); and then instantiate a dummy TournamentDTO, it works.

    This has been an incredibly frustrating issue and a total road block for this very core funcitonality, which my community anticipates greatly. I'm tryign my best not to vent here, but I'm one month away from release and you have to concede that CloudCode is not making any efforts in communicating properly what's the issue.

    I'm flaging this as a Bug because, even if this is an error from my side, something has to be done about this logging for the product to actually be usable.

    Any idea what might be going wrong on this endpoint?
  2. samg-unity


    Unity Technologies

    Mar 23, 2021
    Hi @ANLevant,

    I've managed to find the logs for your project based on the module's function name and can see that the C# module resource was failing to return a response hence the unexpected 500 error. I was able to find some further stack trace logs which I've shared below which I hope are useful. From the log output I suspect the code is hitting an infinite loop somewhere in the GenerateBrackets logic which is preventing the C# module resource from shipping the logs, we'll have to do some further testing on our side to verify thats the case and see about how we handle these types of exceptions better.

    (Please note I've obfuscated the module name in the output)

    Code (CSharp):
    1. 2024-04-08 21:28:45.718
    2. Stack overflow.
    3. 2024-04-08 21:28:45.724
    4. Repeat 24409 times:
    5. 2024-04-08 21:28:45.724
    6. --------------------------------
    8. >>> at xxxxxModule.TournamentManager.CreateTournamentStructure(xxxxModule.TournamentNode) <<<
    10. 2024-04-08 21:28:45.724
    11. --------------------------------
    12. 2024-04-08 21:28:45.724
    13.    at xxxxModule.TournamentManager.GenerateBrackets(xxxxModule.TournamentDTO)
    14. 2024-04-08 21:28:45.724
    15.    at xxxxgModule.TournamentManager+<StartTournament>d__8.MoveNext()
    16. 2024-04-08 21:28:45.724
    17.    at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
    18. 2024-04-08 21:28:45.724
    19.    at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1+AsyncStateMachineBox`1[[System.__Canon, System.Private.CoreLib, Version=, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[xxxxxModule.TournamentManager+<StartTournament>d__8, xxxxxModule, Version=, Culture=neutral, PublicKeyToken=null]].MoveNext(System.Threading.Thread)
    20. 2024-04-08 21:28:45.724
    21.    at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Runtime.CompilerServices.IAsyncStateMachineBox, Boolean)
    22. 2024-04-08 21:28:45.724
    23.    at System.Threading.Tasks.Task.RunContinuations(System.Object)
    24. 2024-04-08 21:28:45.724
    25.    at xxxxxModule.TournamentManager+<GetTournamentByCode>d__13.MoveNext()
    26. ...
    In the mean time, my best suggestion would be to create a unit test for the function to see if that highlights the issue
    GabKBelmonte likes this.
  3. ANLevant


    Jun 10, 2014
    Thank you very very veeeery much. This is exactly what I neeeded. Perhaps the break condition of the method is never being hit. Iwill investigate the issue with the logs. I'm new to Cloud Code Services, I've mostly coded backend solutions with Java and Amazon / Kubernetes. Knowing that I can implement Unit Tests is indeed a very good thing. Thanks again!
    samg-unity likes this.