エラーコード
すべてのエラーには安定したコードがあります。SDK も同じコードを使用し(Unity では enum)、リクエストがサーバーに届く前に発生する問題用のコードもいくつか追加されています。
コードのコメントと API 名は、SDK と一致させるため英語のままにしています。
このページの内容
API エラー#
| コード | HTTP | Unity | 発生条件 | リトライ可否 |
|---|---|---|---|---|
validation | 400, 422 | Validation | 入力が無効です。details.fields で該当するフィールドがわかります。 | 不可 |
unauthorized | 401 | Unauthorized | キーが間違っているか、プレイヤートークンがない、期限切れ、または失効しています。 | 不可 |
forbidden | 403 | Forbidden | プロジェクトが停止中、サーバー専用のエンドポイント、または HTTPS が必要です。 | 不可 |
plan_limit | 403 | PlanLimit | プランの上限(プレイヤー数、エントリー数、ストレージなど)に達しました。データは削除されません。 | 不可 |
not_found | 404 | NotFound | 不明なエンドポイント、リーダーボード、プレイヤー、またはセーブキーです。 | 不可 |
conflict | 409 | Conflict | すでに完了しています(例: この期間の報酬は受け取り済み)。 | 不可 |
revision_mismatch | 409 | RevisionMismatch | クラウドセーブがほかのデバイスで変更されました。 | 不可 |
rate_limited | 429 | RateLimited | 1 分あたりのリクエストが多すぎるか、リーダーボードのクールダウン中です。Retry-After の秒数だけ待機してください。 | 可 |
quota_exceeded | 429 | QuotaExceeded | アカウントの 1 日あたりのリクエストクォータを使い切りました。00:00 UTC にリセットされます。 | 不可 |
server_error | 500 | ServerError | サーバーで問題が発生しました。安全なリクエストは SDK によってリトライされます。 | 可 |
SDK 固有のエラー#
| コード | HTTP | Unity | 発生条件 | リトライ可否 |
|---|---|---|---|---|
network | — | Network | サーバーに接続できませんでした。 | 可 |
timeout | — | Timeout | リクエストがタイムアウト時間を超えました。 | 可 |
not_configured | — | NotConfigured | ベース URL、プロジェクト ID、またはクライアントキーが未設定か無効です。 | 不可 |
not_signed_in | — | NotSignedIn | ログイン前、またはセッションの期限切れ後にプレイヤー向けの呼び出しを行いました。 | 不可 |
signature_invalid | — | SignatureInvalid | リモートコンフィグの検証に失敗したため、使用されませんでした。 | 不可 |
parse_error | — | ParseError | レスポンスを読み取れませんでした(通常はプロキシや HTML のエラーページが原因です)。 | 不可 |
link_expired | — | LinkExpired | アカウント連携ページの有効期限が切れました。最初からやり直してください。 | 不可 |
link_cancelled | — | LinkCancelled | アカウント連携のフローがキャンセルされました。 | 不可 |
エラーの処理#
message はプレイヤーではなく開発者向けに表示し、処理はコードで分岐してください。リトライ可能なエラーのみをリトライし、ログページでリクエストを見つけられるようにリクエスト ID を記録してください。
var top = await Majacloud.Leaderboards.GetTopAsync("coins", 10);
if (top.Ok)
{
foreach (var entry in top.Value.Entries)
Debug.Log($"#{entry.Rank} {entry.PlayerName} {entry.Score}");
}
else if (top.Error.IsRetryable)
{
// Network, timeout, 5xx or rate limit: try again later
Debug.Log("Retry in " + top.Error.RetryAfterSeconds + " s");
}
else
{
Debug.LogWarning(top.Error.Code + ": " + top.Error.Message + " (" + top.Error.RequestId + ")");
}var top := await Majacloud.leaderboards.get_top("coins", 10)
if top.ok:
for entry in top.value.entries:
print("#%d %s %d" % [entry.rank, entry.player_name, entry.score])
elif top.is_retryable():
# Network, timeout, 5xx or rate limit: try again later
print("Retry in ", top.retry_after, " s")
else:
push_warning("%s: %s (%s)" % [top.error, top.message, top.request_id])const top = await mc.leaderboards.getTop('coins', { limit: 10 });
if (top.ok) {
for (const entry of top.value.entries) {
console.log(`#${entry.rank} ${entry.player_name} ${entry.score}`);
}
} else if (top.error.retryable) {
// Network, timeout, 5xx or rate limit: try again later
console.log('Retry in', top.error.retryAfter, 's');
} else {
console.warn(`${top.error.code}: ${top.error.message} (${top.error.requestId})`);
}// Success
{ "ok": true, "entries": [ … ], "total": 42 }
// Error (HTTP 4xx/5xx)
{
"ok": false,
"error": {
"code": "rate_limited",
"message": "Project rate limit reached. Try again in a minute.",
"request_id": "6f1c2a9e-…",
"details": { "limit": 120, "window": "minute" }
}
}