Mã lỗi
Mọi lỗi đều có mã ổn định. Các SDK dùng cùng các mã này (Unity dùng enum), cộng thêm vài mã cho các sự cố xảy ra trước khi yêu cầu đến được máy chủ.
Chú thích trong mã và tên API được giữ nguyên tiếng Anh để khớp với SDK.
Trên trang này
Lỗi API#
| Mã | HTTP | Unity | Khi nào | Thử lại? |
|---|---|---|---|---|
validation | 400, 422 | Validation | Dữ liệu đầu vào không hợp lệ; details.fields cho biết trường nào. | Không |
unauthorized | 401 | Unauthorized | Sai khóa, hoặc token người chơi bị thiếu, hết hạn hay đã bị thu hồi. | Không |
forbidden | 403 | Forbidden | Dự án bị tạm ngưng, endpoint chỉ dành cho máy chủ, hoặc bắt buộc HTTPS. | Không |
plan_limit | 403 | PlanLimit | Đã chạm giới hạn của gói (người chơi, mục xếp hạng, dung lượng…). Không dữ liệu nào bị xóa. | Không |
not_found | 404 | NotFound | Endpoint, bảng xếp hạng, người chơi hoặc khóa bản lưu không tồn tại. | Không |
conflict | 409 | Conflict | Thao tác đã được thực hiện, ví dụ phần thưởng đã được nhận trong kỳ này. | Không |
revision_mismatch | 409 | RevisionMismatch | Bản lưu đám mây đã bị thay đổi trên một thiết bị khác. | Không |
rate_limited | 429 | RateLimited | Quá nhiều yêu cầu mỗi phút, hoặc đang trong thời gian chờ của bảng xếp hạng. Hãy chờ Retry-After giây. | Có |
quota_exceeded | 429 | QuotaExceeded | Tài khoản đã dùng hết hạn mức yêu cầu hằng ngày; hạn mức được đặt lại lúc 00:00 UTC. | Không |
server_error | 500 | ServerError | Đã xảy ra lỗi trên máy chủ. SDK sẽ tự thử lại các yêu cầu an toàn. | Có |
Lỗi chỉ có ở SDK#
| Mã | HTTP | Unity | Khi nào | Thử lại? |
|---|---|---|---|---|
network | — | Network | Không thể kết nối đến máy chủ. | Có |
timeout | — | Timeout | Yêu cầu mất nhiều thời gian hơn thời gian chờ tối đa. | Có |
not_configured | — | NotConfigured | Base URL, ID dự án hoặc khóa client bị thiếu hoặc không hợp lệ. | Không |
not_signed_in | — | NotSignedIn | Lệnh gọi của người chơi trước khi đăng nhập, hoặc sau khi phiên đã hết hạn. | Không |
signature_invalid | — | SignatureInvalid | Cấu hình từ xa không vượt qua bước xác minh và đã không được dùng. | Không |
parse_error | — | ParseError | Không thể đọc phản hồi (thường do proxy hoặc trang lỗi HTML). | Không |
link_expired | — | LinkExpired | Trang liên kết tài khoản đã hết hạn; hãy bắt đầu lại. | Không |
link_cancelled | — | LinkCancelled | Luồng liên kết tài khoản đã bị hủy. | Không |
Xử lý lỗi#
Hiển thị message cho nhà phát triển, không phải cho người chơi; hãy rẽ nhánh theo mã lỗi. Chỉ thử lại các lỗi có thể thử lại, và ghi log ID yêu cầu để tìm lại yêu cầu đó trên trang Nhật ký.
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" }
}
}