ドキュメント

サポート

Cloud Code

エラー処理

Handle errors in your modules using error codes and custom error-handling logic.
読み終わるまでの所要時間 2 分最終更新 23日前

モジュール内でエラーを処理する方法を説明します。

エラーコード

Cloud Code は、モジュールが例外をスローした場合に
422
ステータスエラーを返します。
エラー処理ロジックでは、Cloud Code API エラーレスポンスから返されるエラーメッセージのかわりにエラーコードまたはエラータイプを使用します。エラーメッセージは将来変更される可能性がありますが、エラーコードとタイプは同じままになります。

エラーのラップ

エラーを処理するにはコードを
try
/
catch
ブロックにラップします。エラーが発生した場合は、それをログに記録し、クライアントにエラーを返すことができます。
例えば、ラップされない関数を使用できます。
[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
ブロックを追加してエラーを処理する場合は、より具体的なエラーメッセージを返すことができます。エラーをログに記録することもできます。
[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 Cloud Dashboard でログを確認できます。エラーに関する詳細を取得するには、Products (製品) > Cloud Code > Logs (ログ) を選択します。

リクエストのバッチ処理によるエラー処理

リクエストのバッチ処理の詳細については、リクエストのバッチ処理 を参照してください。

ステータスコード

Cloud Code C# SDK が不成功のステータスコードを返すたびに、SDK は
ApiException
例外をスローします。この例外を使用して、ステータスコードとエラーメッセージを取得できます。
ApiException
例外を捕捉して処理するか、エラーをログに記録して再スローできます。これは、
ApiResponse
オブジェクト内でステータスコードを確認する必要がないことを意味します。

処理されないエラー

Cloud Code は、無限ループなどのメモリリークに起因する例外を処理できません。モジュールがメモリ制限を超えると、ワーカーは最終的にクラッシュします。Cloud Code は
async void
パターンの例外を処理できません。常に
Task
または
Task<T>
を返します。非同期プログラミングのベストプラクティスについては、Microsoft の公式ドキュメント を参照してください。

ロギング

モジュールのデバッグに役立てるために、エラーと警告を
ILogger
インターフェースでログに記録できます。
Cloud Code は、
playerId
environmentId
projectId
のような属性をログに自動的に追加するため、それらをログメッセージに追加する必要はありません。
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 Cloud Dashboard でログをクエリするのに役立ちます。
_logger.LogDebug("debug message");_logger.LogInformation("info message");_logger.LogWarning("warning message");_logger.LogError("error message");_logger.LogCritical("critical message");
ログの表示とフィルター処理を行うには、Unity Cloud Dashboard に移動し、Products (製品) > Cloud Code > Logs (ログ) を選択します。 詳細については、ログの発行 を参照してください。