错误处理
了解如何处理模块中的错误。
错误代码
如果模块抛出异常,Cloud Code 将返回 422
状态错误。
对于错误处理逻辑,请使用从 Cloud Code API 错误响应返回的错误代码或错误类型,而不是错误消息。错误消息将来可能会更改,但错误代码和类型将保持不变。
对错误进行包装
请将代码包装在 try
/catch
代码块中来处理错误。如果发生错误,您可以记录该错误并向客户端返回一个错误。
例如,您可以编写一个未包装的函数:
C#
[CloudCodeFunction("IncrementBalance")]
public async Task<ApiResponse<CurrencyBalanceResponse>> IncrementPlayerBalance(IGameApiClient gameApiClient, IExecutionContext ctx, string currencyId)
{
return await gameApiClient.EconomyCurrencies.IncrementPlayerCurrencyBalanceAsync(ctx, ctx.ServiceToken, ctx.ProjectId, ctx.PlayerId, currencyId, new CurrencyModifyBalanceRequest(currencyId, 10));
}
这个未包装的函数返回一般错误:
{
"type": "problems/invocation",
"title": "Unprocessable Entity",
"status": 422,
"detail": "Invocation Error",
"instance": null,
"code": 9009,
"details": [
{
"message": "Error executing Cloud Code function. Exception type: ApiException. Message: Bad Request",
"name": "ScriptRunner.Exceptions.CloudCodeRuntimeException",
"stackTrace": [
"at Unity.Services.CloudCode.Shared.HttpApiClient.ToApiResponse[T](HttpResponseMessage response)",
"at Unity.Services.CloudCode.Shared.HttpApiClient.SendAsync[T](String path, HttpMethod method, ApiRequestOptions options, IApiConfiguration configuration, CancellationToken cancellationToken)",
"at Unity.Services.Economy.Api.EconomyCurrenciesApi.IncrementPlayerCurrencyBalanceAsync(IExecutionContext executionContext, String accessToken, String projectId, String playerId, String currencyId, CurrencyModifyBalanceRequest currencyModifyBalanceRequest, String configAssignmentHash, String unityInstallationId, String analyticsUserId, CancellationToken cancellationToken)",
"at Sample.HelloWorld.IncrementBalanceUnhandled(IGameApiClient gameApiClient, IExecutionContext ctx, String currencyId) in Sample/Main/HelloWorld.cs:line 148"
]
}
]
}
如果添加 try
/catch
代码块来处理错误,则可以返回更具体的错误消息。您还可以记录错误:
C#
[CloudCodeFunction("IncrementBalance")]
public async Task<ApiResponse<CurrencyBalanceResponse>> IncrementPlayerBalance(IGameApiClient gameApiClient, IExecutionContext ctx, string currencyId)
{
try
{
return await gameApiClient.EconomyCurrencies.IncrementPlayerCurrencyBalanceAsync(ctx, ctx.ServiceToken,
ctx.ProjectId, ctx.PlayerId, currencyId, new CurrencyModifyBalanceRequest(currencyId, 10));
}
catch (ApiException e)
{
_logger.LogError("Failed to increment {currencyId} balance for the player. Error: {error}", currencyId, e.Message);
throw new Exception($"Failed to increment balance for playerId {ctx.PlayerId}. Error: {e.Message}");
}
}
以下已包装的函数返回一条包含更多详细信息的错误消息:
{
"type": "problems/invocation",
"title": "Unprocessable Entity",
"status": 422,
"detail": "Invocation Error",
"instance": null,
"code": 9009,
"details": [
{
"message": "Error executing Cloud Code function. Exception type: Exception. Message: Failed to increment balance for playerId 7wCG6G0d1PU6WSVZPG9oQ1op97xd. Error: Bad Request",
"name": "ScriptRunner.Exceptions.CloudCodeRuntimeException",
"stackTrace": [
"at Sample.HelloWorld.IncrementPlayerBalance(IGameApiClient gameApiClient, IExecutionContext ctx, String currencyId) in Sample/Main/HelloWorld.cs:line 165"
]
}
]
}
您可以在 Unity Dashboard(Unity 后台)中查看日志。要获取更多有关该错误的详细信息,请选择 Live Ops > Cloud Code > Logs(日志)。
状态代码
每当 Cloud Code C# SDK 返回不成功的状态代码时,该 SDK 都会抛出 ApiException
异常。您可以使用此异常来获取状态代码和错误消息。
您可以捕获 ApiException
异常并对其进行处理,或者记录并重新抛出该错误。这意味着您不必检查 ApiResponse
对象中的状态代码。
Logging
为了帮助您调试模块,您可以使用 ILogger
接口记录错误和警告。
Cloud Code 会自动将 playerId
、environmentId
和 projectId
等属性添加到日志中,因此您无需将它们添加到日志消息中。
C#
public class HelloWorld
{
private readonly ILogger<HelloWorld> _logger;
public HelloWorld(ILogger<HelloWorld> logger)
{
_logger = logger;
}
[CloudCodeFunction("IncrementBalance")]
public async Task<ApiResponse<CurrencyBalanceResponse>> IncrementPlayerBalance(IGameApiClient gameApiClient, IExecutionContext ctx, string currencyId)
{
try
{
var res = await gameApiClient.EconomyCurrencies.IncrementPlayerCurrencyBalanceAsync(ctx, ctx.ServiceToken,
ctx.ProjectId, ctx.PlayerId, currencyId, new CurrencyModifyBalanceRequest(currencyId, 10));
_logger.LogInformation("Incremented currency {currencyId} balance by {amount}", currencyId, 10);
return res;
}
catch (ApiException e)
{
_logger.LogError("Failed to increment {currencyId} balance for the player. Error: {error}", currencyId, e.Message);
throw new Exception($"Failed to increment balance for playerId {ctx.PlayerId}. Error: {e.Message}");
}
}
public class ModuleConfig : ICloudCodeSetup
{
public void Setup(ICloudCodeConfig config)
{
config.Dependencies.AddSingleton(GameApiClient.Create());
}
}
}
您可以记录不同级别的消息。这些级别可以帮助您在 Unity Dashboard(Unity 后台)中查询日志。
C#
_logger.LogDebug("debug message");
_logger.LogInformation("info message");
_logger.LogWarning("warning message");
_logger.LogError("error message");
_logger.LogCritical("critical message");
要查看和过滤日志,请导航到 Unity Dashboard(Unity 后台)并选择 Live Ops > Cloud Code > Logs(日志)。
如需了解更多信息,请参阅发出日志文档。