رفتن به محتوای اصلی
هوشوانا

خطاها و کدهای خطا

فهرست کامل کدهای خطای API هوشوانا با وضعیت HTTP، معنی و راه‌حل هر کدام، به همراه راهنمای تلاش دوباره و نمونه‌کد مدیریت خطا در Python و Node.js.

آخرین به‌روزرسانی:

وقتی درخواستی به API هوشوانا با مشکل روبه‌رو شود، پاسخ یک کد وضعیت HTTP غیر ۲۰۰ و یک بدنه‌ی JSON با جزئیات خطا دارد. این صفحه همه‌ی کدهای خطا و کاری را که باید در هر مورد انجام دهید توضیح می‌دهد.

قالب خطا

قالب خطا با OpenAI سازگار است، بنابراین SDKها آن را به‌درستی تشخیص می‌دهند. پیام خطا به فارسی است تا بتوانید آن را مستقیم در لاگ‌ها بخوانید:

JSON
{
  "error": {
    "message": "موجودی کیف پول برای این درخواست کافی نیست. لطفاً حساب خود را شارژ کنید.",
    "type": "billing_error",
    "code": "insufficient_balance"
  }
}
  • code: شناسه‌ی پایدار خطا. منطق برنامه را بر اساس این فیلد بنویسید.
  • message: توضیح قابل خواندن برای انسان. ممکن است متنش تغییر کند، پس در کد به آن وابسته نشوید.
  • type: دسته‌ی کلی خطا.

جدول کدهای خطا

کدHTTPمعنیچه کار کنید
invalid_request400درخواست نامعتبر است: فیلد الزامی ندارد، نوع داده اشتباه است یا پارامتری با مدل سازگار نیستپیام خطا را بخوانید و بدنه را اصلاح کنید. تلاش دوباره بی‌فایده است
invalid_api_key401کلید ارسال نشده، اشتباه است یا باطل شدههدر Authorization یا x-api-key و مقدار متغیر محیطی را بررسی کنید
insufficient_balance402موجودی کیف پول کمتر از حداقل لازم یا هزینه‌ی تخمینی درخواست استکیف پول را شارژ کنید یا max_tokens را کم کنید
spend_cap_reached402سقف هزینه‌ی روزانه، ماهانه یا بودجه‌ی کل کلید یا حساب پر شدهتا دوره‌ی بعد صبر کنید یا سقف را در قوانین افزایش دهید
key_paused403کلید موقتاً متوقف شده استکلید را در داشبورد دوباره فعال کنید
key_expired403تاریخ انقضای کلید گذشته استکلید جدید بسازید یا تاریخ انقضا را تمدید کنید
ip_not_allowed403IP یا referrer درخواست در فهرست مجاز کلید نیستIP سرور را به فهرست مجاز اضافه کنید
endpoint_not_allowed403کلید اجازه‌ی استفاده از این endpoint را نداردendpoint را در قوانین کلید مجاز کنید یا از کلید دیگری استفاده کنید
model_not_allowed403مدل وجود دارد ولی قوانین کلید یا حساب آن را مجاز نمی‌دانندمدل یا گروهش را در قوانین مجاز کنید یا مدل مجاز دیگری انتخاب کنید
model_not_found404شناسه‌ی مدل اشتباه است یا مدل در دسترس نیستشناسه را با GET /models یا کاتالوگ مدل‌ها مقایسه کنید
rate_limited429از محدودیت تعداد درخواست یا توکن در دقیقه عبور کرده‌ایدپس از مدت هدر Retry-After با backoff تلاش کنید. محدودیت نرخ
upstream_error502ارائه‌دهنده‌ی مدل خطا داده و جایگزین خودکار هم موفق نبودهبا backoff دوباره تلاش کنید. اگر ادامه داشت، وضعیت سرویس را ببینید
upstream_timeout504ارائه‌دهنده‌ی مدل در زمان مقرر پاسخ ندادهدوباره تلاش کنید، از استریم استفاده کنید یا ورودی را کوتاه‌تر کنید

ترتیب بررسی قوانین که مشخص می‌کند کدام خطا زودتر برمی‌گردد، در قوانین کلید آمده است.

کدام خطاها ارزش تلاش دوباره دارند؟

دستهکدهاتلاش دوباره؟
موقتیrate_limited، upstream_error، upstream_timeoutبله، با backoff نمایی
مالیinsufficient_balance، spend_cap_reachedخیر، تا وقتی موجودی یا سقف تغییر نکند
دسترسی و تنظیماتinvalid_api_key، key_paused، key_expired، ip_not_allowed، endpoint_not_allowed، model_not_allowedخیر، تنظیمات را اصلاح کنید
درخواستinvalid_request، model_not_foundخیر، درخواست را اصلاح کنید

هوشوانا خودش در صورت مشکل یک ارائه‌دهنده، درخواست را به مسیرهای جایگزین می‌فرستد. پس وقتی upstream_error می‌گیرید، یعنی این تلاش‌های خودکار هم موفق نبوده‌اند و چند ثانیه صبر قبل از تلاش دوباره منطقی است.

مدیریت خطا در Python

SDK رسمی OpenAI برای خطاها کلاس‌های مشخص دارد. کد هوشوانا در e.code (یا داخل e.body) در دسترس است:

Python
import os
import random
import time

import openai
from openai import OpenAI

client = OpenAI(
    base_url="https://hooshvana.ir/api/v1",
    api_key=os.environ["HOOSHVANA_API_KEY"],
    max_retries=0,  # we handle retries ourselves below
)

RETRYABLE = {"rate_limited", "upstream_error", "upstream_timeout"}

def chat(messages, model="openai/gpt-4o-mini", attempts=5):
    for attempt in range(attempts):
        try:
            return client.chat.completions.create(model=model, messages=messages)
        except openai.APIStatusError as e:
            code = getattr(e, "code", None)
            request_id = e.response.headers.get("x-hooshvana-request-id")
            if code not in RETRYABLE or attempt == attempts - 1:
                print(f"failed: status={e.status_code} code={code} request_id={request_id}")
                raise
            retry_after = e.response.headers.get("retry-after")
            delay = float(retry_after) if retry_after else min(30, 2 ** attempt) + random.random()
            time.sleep(delay)
        except openai.APIConnectionError:
            if attempt == attempts - 1:
                raise
            time.sleep(min(30, 2 ** attempt) + random.random())

try:
    reply = chat([{"role": "user", "content": "سلام"}])
    print(reply.choices[0].message.content)
except openai.APIStatusError as e:
    if getattr(e, "code", None) == "insufficient_balance":
        print("Please top up the wallet.")

SDK به‌طور پیش‌فرض خودش چند بار روی خطاهای ۴۲۹ و ۵xx تلاش دوباره می‌کند. اگر منطق خودتان را می‌نویسید، مثل نمونه‌ی بالا max_retries=0 بگذارید تا تلاش‌ها دو برابر نشوند.

مدیریت خطا در Node.js

JavaScript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://hooshvana.ir/api/v1",
  apiKey: process.env.HOOSHVANA_API_KEY,
  maxRetries: 0,
});

const RETRYABLE = new Set(["rate_limited", "upstream_error", "upstream_timeout"]);
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
// Works with both SDK v4 (plain object) and v5 (Headers instance)
const header = (h, name) => (typeof h?.get === "function" ? h.get(name) : h?.[name]);

async function chat(messages, model = "openai/gpt-4o-mini", attempts = 5) {
  for (let attempt = 0; attempt < attempts; attempt++) {
    try {
      return await client.chat.completions.create({ model, messages });
    } catch (err) {
      if (!(err instanceof OpenAI.APIError)) throw err;
      const code = err.code;
      const requestId = header(err.headers, "x-hooshvana-request-id");
      const retryable = RETRYABLE.has(code) || err instanceof OpenAI.APIConnectionError;
      if (!retryable || attempt === attempts - 1) {
        console.error("failed", { status: err.status, code, requestId, message: err.message });
        throw err;
      }
      const retryAfter = Number(header(err.headers, "retry-after"));
      const delay = retryAfter > 0
        ? retryAfter * 1000
        : Math.min(30000, 2 ** attempt * 1000) + Math.random() * 1000;
      await sleep(delay);
    }
  }
}

const reply = await chat([{ role: "user", content: "سلام" }]);
console.log(reply.choices[0].message.content);

خطا در میانه‌ی استریم

اگر استریم شروع شده باشد و بعد خطایی رخ دهد، کد وضعیت HTTP دیگر قابل تغییر نیست (۲۰۰ ارسال شده است). در این حالت یک رویداد خطا در استریم ارسال و اتصال بسته می‌شود. SDKها این رویداد را به استثنا تبدیل می‌کنند. حلقه‌ی خواندن استریم را در try قرار دهید و در صورت خطا، متن جزئی را یا دور بریزید یا به کاربر اطلاع دهید که پاسخ ناقص است.

نکته‌های کاربردی

  • همیشه x-hooshvana-request-id را همراه خطا در لاگ برنامه‌ی خود ثبت کنید. با آن می‌توانید درخواست را در لاگ درخواست‌ها پیدا کنید.
  • پیام خطای فارسی را می‌توانید به کاربر نهایی هم نشان دهید، ولی برای خطاهای مالی یا دسترسی، پیام عمومی‌تری نمایش دهید و جزئیات را فقط در لاگ نگه دارید.
  • برای جلوگیری از توقف سرویس به خاطر insufficient_balance، آستانه‌ی هشدار موجودی کم را در تنظیمات حساب فعال کنید.