گیم روت
API و توسعه‌دهندگان

خطاها

API برای موفقیت کدهای 2xx و برای خطا کدهای 4xx و 5xx برمی‌گرداند. بدنه همه خطاها ساختار یکسانی دارد، پس کافی است یک بار مدیریتش کنید.

ساختار خطا#

JSON
{
  "error": {
    "code": "VALIDATION",
    "message": "حداکثر ۱۲۰ کاراکتر مجاز است",
    "fields": { "title": "حداکثر ۱۲۰ کاراکتر مجاز است" }
  }
}
فیلدتوضیح
codeکد ثابت انگلیسی. منطق برنامه را روی این فیلد بنا کنید؛ تغییر نمی‌کند.
messageتوضیح فارسی برای نمایش به کاربر. ممکن است متنش بهتر شود، پس با آن مقایسه نکنید.
fieldsفقط در خطاهای اعتبارسنجی: پیام هر فیلد، به تفکیک مسیر آن (مثل socials.discord).

کدهای وضعیت#

HTTPمعنیکار درست
200 / 201موفق / ساخته شد—
204موفق، بدون بدنه (حذف)—
400ورودی نامعتبرfields را بخوانید و ورودی را اصلاح کنید؛ تکرار بی‌فایده است.
401کلید ارسال نشده، نامعتبر یا باطل‌شدهکلید را بررسی کنید.
403کلید معتبر است ولی اجازه این کار را ندارددسترسی کلید یا نقش سازنده را بررسی کنید.
404سرور یا مورد پیدا نشدنامک را بررسی کنید؛ سرورهای تأییدنشده یا تعلیق‌شده در مسیرهای خواندنی دیده نمی‌شوند.
429سقف درخواست پر شدهبه اندازه Retry-After صبر کنید.
500 / 503خطای سمت گیم روتبا فاصله افزایشی دوباره تلاش کنید.

فهرست کدهای خطا#

کدHTTPتوضیح
API_KEY_REQUIRED401این مسیر بدون کلید کار نمی‌کند (مسیرهای مدیریتی و /me).
INVALID_API_KEY401کلید با قالب gr_live_… نیست یا وجود ندارد.
API_KEY_REVOKED401کلید باطل شده است.
ACCOUNT_BANNED403حساب سازنده کلید مسدود است.
INSUFFICIENT_SCOPE403کلید دسترسی لازم (مثلاً news:write) را ندارد.
KEY_NOT_SERVER_BOUND403برای مدیریت، کلید حساب کافی نیست؛ کلید سرور لازم است.
KEY_SERVER_MISMATCH403کلید برای سرور دیگری ساخته شده است.
NO_SERVER_PERMISSION403سازنده کلید دیگر مجوز لازم را در تیم سرور ندارد.
SERVER_NOT_FOUND404سروری با این نامک یا شناسه نیست، یا هنوز تأیید نشده است.
NOT_FOUND404مورد دیگری (مثلاً خبر) پیدا نشد.
VALIDATION400ورودی با قواعد نمی‌خواند؛ جزئیات در fields.
INVALID_MEDIA400imageUrl تصویری نیست که در پنل گیم روت بارگذاری شده باشد.
RATE_LIMITED429سقف درخواست در دقیقه پر شده است.
INTERNAL500خطای پیش‌بینی‌نشده. اگر تکرار شد گزارش دهید.

مدیریت خطا در کد#

JavaScript
async function api(path, init = {}) {
  const res = await fetch(`https://gameroute.ir/api/v1${path}`, {
    ...init,
    headers: { Authorization: `Bearer ${process.env.GAMEROUTE_API_KEY}`, 'Content-Type': 'application/json', ...init.headers },
  });
  if (res.status === 204) return null;
  const body = await res.json();
  if (!res.ok) {
    const err = new Error(body.error.message);
    err.code = body.error.code;
    err.status = res.status;
    err.fields = body.error.fields;
    throw err;
  }
  return body;
}

try {
  await api('/servers/iran-craft/news', { method: 'POST', body: JSON.stringify({ body: 'سلام' }) });
} catch (e) {
  if (e.code === 'NO_SERVER_PERMISSION') console.error('نقش سازنده کلید تغییر کرده است');
  else throw e;
}
Python
import requests

class GamerouteError(Exception):
    def __init__(self, status, code, message, fields=None):
        super().__init__(message)
        self.status, self.code, self.fields = status, code, fields or {}

def api(method, path, **kw):
    res = requests.request(method, f"https://gameroute.ir/api/v1{path}", timeout=10, **kw)
    if res.status_code == 204:
        return None
    body = res.json()
    if not res.ok:
        e = body["error"]
        raise GamerouteError(res.status_code, e["code"], e["message"], e.get("fields"))
    return body