How effectively debug cloud code?

Hi,
We are thinking about using UGS and Cloud Code in our project. One thing we have doubts about is how to debug cloude code effectively. At this point we have established that debugging would be based on the logger and unit tests, but are there any other solutions? Ideally, the cloude code could be called locally and debugged using the debugger and breakpoints (but at the moment we have not found such an option). How do you guys debug your cloude code?

If your cloud code is so complex that you need a debugger despite running unit tests for it, then your cloud code is probably too complex. :wink:

As in: trying to do too many things at once.

Typically cloud code will be either about storing or retrieving values, and testing for correctness (eg is player allowed to do this?). And you will want to send the app or editor a notification - possibly only in debug mode - if anything unexpected happens with details about the unexpected thing (eg try to query player x but this player does not exist).

It is possible to write (not perfectly, but pretty) failsafe, robust code by indiscriminately applying a defensive programming style. Assume any reference could be null, assume any method call could throw an exception, assume any query could fail, assume all input values could have any potential value and handle those cases, assume a dependent service does not respond eg due to maintenance.

Essentially write cloud code so there is no unhandled situation, and inform your endpoint with results in every case, because it could always be a failure. Take for example any cloud API (eg CommonErrorCodes, AuthenticationErrorCodes) and you‘ll notice there is something for every possible situation, no matter how fringe.

But yes, if in doubt, write the cloud code so it can also run locally for unit tests using mock classes and such. Then you can reconstruct any situation locally by adding a test with the same input values or game state that cause an issue.

3 Likes

@CodeSmile Thanks for the explanation :slight_smile:

I wanted to explain this somewhat better, it may come across a bit too much like “just write bug-free code” which of course is not feasible. :wink:

One neat way of handling this is to make any code that works on cloud data not depend on the cloud services to begin with. Instead you add a lightweight data accessor interface that the algorithm works with. Then you can swap the concrete implementation as needed, be it the cloud service accessor or the local test data accessor.

I would do so for any decently complex cloud code, such as a “random item generator” that relies on cloud data.

The cloud version of the “data accessor” should also perform any necessary validation checks, like handling values that don’t exist or are out of range for whatever reason. You could clamp values or use defaults for missing values and/or report/log any such issues as needed, and that same layer would be reusable for any other cloud code algorithm too.

In fact the whole services APIs use this concept, probably also to enable unit testing. For example the CloudServiceWhatever.Instance singleton will always return an interface, and pretty much every other reference used within the APIs is also an interface.

1 Like