รหัสข้อผิดพลาด
ข้อผิดพลาดทุกรายการมีรหัสที่คงที่ 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 | คำขอต่อนาทีมากเกินไป หรือติดคูลดาวน์ของลีดเดอร์บอร์ด ให้รอ Retry-After วินาที | ได้ |
quota_exceeded | 429 | QuotaExceeded | ใช้โควตาคำขอรายวันของบัญชีหมดแล้ว โควตาจะรีเซ็ตเวลา 00:00 UTC | ไม่ |
server_error | 500 | ServerError | เกิดข้อผิดพลาดบนเซิร์ฟเวอร์ SDK จะลองส่งคำขอที่ปลอดภัยใหม่ให้ | ได้ |
ข้อผิดพลาดเฉพาะใน SDK#
| รหัส | HTTP | Unity | เกิดเมื่อ | ลองใหม่? |
|---|---|---|---|---|
network | — | Network | ติดต่อเซิร์ฟเวอร์ไม่ได้ | ได้ |
timeout | — | Timeout | คำขอใช้เวลานานเกินค่า timeout | ได้ |
not_configured | — | NotConfigured | Base URL, Project ID หรือคีย์ไคลเอนต์ไม่มีหรือไม่ถูกต้อง | ไม่ |
not_signed_in | — | NotSignedIn | เรียกในนามผู้เล่นก่อนเข้าสู่ระบบ หรือหลังจากเซสชันหมดอายุ | ไม่ |
signature_invalid | — | SignatureInvalid | รีโมตคอนฟิกไม่ผ่านการตรวจสอบและไม่ถูกนำไปใช้ | ไม่ |
parse_error | — | ParseError | อ่านการตอบกลับไม่ได้ (มักเกิดจากพร็อกซีหรือหน้าข้อผิดพลาดแบบ HTML) | ไม่ |
link_expired | — | LinkExpired | หน้าเชื่อมบัญชีหมดอายุแล้ว ให้เริ่มใหม่ | ไม่ |
link_cancelled | — | LinkCancelled | โฟลว์การเชื่อมบัญชีถูกยกเลิก | ไม่ |
การจัดการข้อผิดพลาด#
แสดง message ให้นักพัฒนาเห็น ไม่ใช่ผู้เล่น และแยกการทำงานตามรหัส ลองใหม่เฉพาะข้อผิดพลาดที่ลองใหม่ได้ และบันทึกรหัสคำขอไว้เพื่อค้นหาคำขอนั้นในหน้าล็อก
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" }
}
}