Sari la conținut
Gestionare erori

Gestionare erori

O cerere care eșuează returnează un cod de stare HTTP și un corp JSON cu un tip de eroare și un mesaj. Această pagină listează fiecare stare, arată corpul de eroare al fiecărui format API și spune ce erori merită retrimise.

SDK-urile ridică un obiect de eroare care poartă codul de stare și câmpurile corpului. Această cerere indică un model care nu există:

import openai
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.shannon-ai.com/v1",
)

try:
    client.chat.completions.create(
        model="no-such-model",
        messages=[{"role": "user", "content": "Hello"}],
    )
except openai.APIStatusError as error:
    print(error.status_code)                           # 400
    print(error.type)                                  # invalid_request_error
    print(error.body["message"])                       # unknown model: no-such-model
    print(error.response.headers.get("x-request-id"))  # the id of this request

Returnează starea 400 și acest corp:

400 JSON
{
  "error": {
    "type": "invalid_request_error",
    "message": "unknown model: no-such-model"
  }
}

Corpul erorii

Există două corpuri. /v1/messages răspunde în formatul Anthropic; fiecare alt endpoint răspunde în formatul OpenAI. În ambele, detaliile sunt în error.type și error.message, deci un singur cititor servește toate endpoint-urile.

401 Format OpenAI
{
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key",
    "code": "invalid_api_key",
    "param": null
  }
}
401 Format Anthropic
{
  "type": "error",
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key"
  }
}
Câmp Tip Descriere
error.type string Felul erorii. Vezi Tipuri de erori mai jos.
error.message string O propoziție pentru un om. Textele din tabelele de mai jos sunt stabile, cu excepția părților variabile, afișate ca <id>, <n> sau ….
error.code string | null Prezent la unele erori în formatul OpenAI: invalid_api_key cu 401, request_too_large cu 413, context_length_exceeded când o conversație este prea lungă, altfel null sau absent. Decide mai întâi după stare și error.type și tratează code ca pe un extra.
error.param null Prezent la aceleași erori ca code. Întotdeauna null.
type string Doar în formatul Anthropic. Întotdeauna error.

Tipuri de erori

Tip Stări Descriere
invalid_request_error 400, 413, 415, 422 Cererea în sine este greșită: un câmp, corpul, id-ul modelului sau o intrare pe care modelul nu o acceptă. Modifică cererea înainte să o trimiți din nou.
authentication_error 401 Cheia API lipsește, este necunoscută sau revocată.
not_found_error 404 Calea nu există.
rate_limit_error 429 Soldul nu acoperă cererea, protecția anti-flood a oprit-o sau modelul este ocupat. Mesajul spune care este cazul.
api_error 500, 502, 503, 504 Cererea era în regulă, iar eroarea este de partea noastră. Trimite-o din nou.
server_error 500 Cererea era în regulă, iar eroarea este de partea noastră. Trimite-o din nou.

Coduri de stare

Stare Tip Mesaj Când
400 invalid_request_error Failed to parse the request body as JSON: … Corpul nu este JSON valid.
400 invalid_request_error unknown model: <id> model nu este un id publicat. Pe /v1/responses, și când model lipsește.
400 invalid_request_error No user message provided Niveluri Shannon: cererea nu conține text de la utilizator.
400 invalid_request_error <id> does not accept image input O imagine a fost trimisă unui model open-weight găzduit care nu acceptă imagini la intrare.
400 invalid_request_error audio and video input are not supported by any hosted model O parte audio sau video a fost trimisă unui model open-weight găzduit.
400 invalid_request_error <id> does not accept response_format S-a cerut ieșire structurată de la un model open-weight găzduit care nu o are.
400 invalid_request_error <id> does not accept response_format json_schema; use json_object O schemă JSON a fost trimisă unui model open-weight găzduit care acceptă doar json_object.
400 invalid_request_error unknown reasoning effort '<value>'; expected off, low, medium or high Efortul de raționament nu este una dintre valorile listate. Modele open-weight găzduite.
400 invalid_request_error count_tokens is available for the hosted open models; unknown model: <id> S-a cerut numărarea token-urilor pentru un model din afara modelelor open-weight găzduite.
401 authentication_error Missing authentication Nu a fost trimisă nicio cheie API.
401 authentication_error Invalid API key Cheia este necunoscută, a fost înlocuită cu una mai nouă sau a fost revocată.
404 not_found_error Not Found Calea nu există, de exemplu /v1/embeddings.
405 api_error Method Not Allowed Calea există, dar nu cu această metodă HTTP.
413 invalid_request_error Failed to buffer the request body: … Corpul cererii este mai mare de 32 MiB.
415 invalid_request_error Expected request with `Content-Type: application/json` Header-ul Content-Type lipsește sau nu este application/json.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … Lipsește un câmp obligatoriu, cum ar fi messages, sau un câmp are tipul JSON greșit.
429 rate_limit_error Quota exceeded. Upgrade your plan at shannon-ai.com/plan Limita de ieșire a cererii este mai mare decât ce a rămas din soldul tău.
429 rate_limit_error Too many requests. Retry in <n>s. Protecție anti-flood: mai mult de 120 de cereri într-un minut pe contul tău. <n> este numărul de secunde până la sfârșitul minutului.
429 rate_limit_error Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan shannon-coder-1 pe /v1/chat/completions și /v1/messages: apelurile Shannon Coder ale planului tău pentru fereastra curentă de 4 ore au fost consumate.
429 rate_limit_error Shannon routes are temporarily busy. Please retry. Modelul este ocupat în acest moment.
500 server_error The model backend failed to answer. Please retry. Modelul nu a produs un răspuns.
500 server_error An internal error occurred. Please retry. O eroare internă în timpul pregătirii cererii.
502 api_error The model backend failed to answer. Please retry. Modelul nu a produs un răspuns. Familia Shannon 3 și modelele open-weight găzduite.
503 api_error Could not verify your quota right now. Please retry. Soldul tău nu a putut fi citit în acest moment.
503 api_error token counting is temporarily unavailable for this model Numărarea token-urilor nu este disponibilă pentru acest model în acest moment.
504 api_error upstream timed out Un model open-weight găzduit a durat mai mult decât limita de timp a unei cereri fără streaming.

Verificările rulează în această ordine: cheia API, corpul cererii, id-ul modelului, protecția anti-flood, soldul. O cerere cu o cheie greșită și un corp greșit returnează deci 401. O cerere refuzată cu o stare 4xx nu este taxată.

Sold și protecție anti-flood

Fiecare cerere este servită în mod egal: nu există niveluri de rată și nici o cotă API separată. Două lucruri pot totuși răspunde cu 429, ambele cu tipul rate_limit_error. Mesajul le deosebește.

Sold

Soldul tău este cota zilnică a planului de azi, care se resetează la 00:00 UTC, și după aceasta creditul tău achiziționat. Chatul și API-ul folosesc același sold.

Fiecare cerere rezervă mai întâi limita ei de ieșire: max_tokens sau max_output_tokens pe /v1/responses, 4,096 când nu trimiți niciuna. Când răspunsul este complet, suma rezervată este înlocuită cu ce a folosit cererea. Dacă suma nu încape în soldul rămas, cererea returnează Quota exceeded înainte ca modelul să înceapă.

Cererile care rulează în același timp rezervă fiecare suma ei. Multe cereri paralele cu un max_tokens mare pot deci epuiza soldul pentru o clipă, chiar dacă fiecare răspuns este scurt. Un max_tokens mai mic rezervă mai puțin.

Protecție anti-flood

Protecția anti-flood permite 120 de cereri pe minut pe cont. Numără contul, nu cheia, pe /v1/chat/completions, /v1/responses și /v1/messages la un loc. Minutul începe cu prima ta cerere.

Cererea cu numărul 121 din acel minut returnează Too many requests. Retry in <n>s. și nu costă nimic. Cererile refuzate se numără și ele, deci un client care retrimite fără să aștepte rămâne refuzat până se termină minutul. Așteaptă cele <n> secunde din mesaj.

Cererile trimise în paralel nu sunt refuzate pentru că sunt paralele. Ele așteaptă la coadă și primesc răspuns pe rând.

GET /v1/models și endpoint-urile de numărare a token-urilor nu sunt numărate.

Mai multe despre limite și sold și unde îți vezi propriul sold și propria utilizare: Limite și sold Chei și utilizare

Ce merită reîncercat

Retrimite o cerere doar când aceeași cerere poate reuși. SDK-urile OpenAI și Anthropic reîncearcă deja singure de două ori răspunsurile 429 și 5xx; setează max_retries (maxRetries în JavaScript) pentru a schimba asta.

Eroare Se retrimite? Cum
400, 404, 405, 413, 415, 422 Nu. Corectează mai întâi cererea. Mesajul indică câmpul, modelul sau intrarea care este greșită.
401 Nu. Folosește o cheie validă. Creează sau înlocuiește cheia pe pagina Chei și utilizare.
429 Too many requests Da, după așteptare. Așteaptă numărul de secunde din mesaj, apoi trimite aceeași cerere.
429 Quota exceeded Nu așa cum este. Redu max_tokens, așteaptă resetarea zilnică la 00:00 UTC sau adaugă credit.
429 Shannon Coder call quota reached Da, în fereastra următoare. Ferestrele încep la fiecare 4 ore de la 00:00 UTC. Un alt model răspunde imediat.
429 … temporarily busy Da. Așteaptă câteva secunde, apoi mai mult la fiecare încercare ulterioară.
500, 502, 503 Da. Așteaptă 1 secundă, apoi 2, 4 și 8. Oprește-te după câteva încercări și raportează id-ul cererii.
504 Da. Trimite-o cu stream setat la true: limita de timp se aplică răspunsurilor fără streaming.

O buclă de reîncercare care urmează acest tabel:

import re
import time

import openai
from openai import OpenAI

# max_retries=0: this loop does the retrying, the SDK does not add its own.
client = OpenAI(api_key="YOUR_API_KEY", base_url="https://api.shannon-ai.com/v1", max_retries=0)


def create_with_retry(attempts=5, **request):
    for attempt in range(attempts):
        try:
            return client.chat.completions.create(**request)
        except openai.RateLimitError as error:
            text = str(error)
            flood = re.search(r"Retry in (\d+)s", text)
            if flood:
                time.sleep(int(flood.group(1)))   # flood protection: wait out the minute
            elif "temporarily busy" in text:
                time.sleep(2 ** attempt)
            else:
                raise                             # balance: a wait of seconds does not help
        except (openai.InternalServerError, openai.APIConnectionError):
            time.sleep(2 ** attempt)              # 1, 2, 4, 8 seconds
    raise RuntimeError("the request failed after all attempts")


response = create_with_retry(
    model="shannon-3",
    messages=[{"role": "user", "content": "Hello"}],
)
print(response.choices[0].message.content)

Erori în interiorul unui stream

Un stream are starea 200 de la primul octet. O eroare de după aceea sosește ca eveniment în interiorul stream-ului: un chunk cu un membru error pe /v1/chat/completions, un eveniment error pe /v1/messages, un eveniment response.failed sau error pe /v1/responses. Evenimentele de închidere ale stream-ului urmează totuși. Tratează un astfel de răspuns ca eșuat și retrimite cererea, ca la o stare 5xx.

O conversație mai lungă decât fereastra de context a modelului este raportată în acest mod, cu tipul invalid_request_error și codul context_length_exceeded. Scurtează conversația înainte să o trimiți din nou.

Cadrele exacte sunt descrise la streaming. Streaming

Id-uri de cerere

Fiecare răspuns, inclusiv erorile, are un header x-request-id. Este valoarea trimisă de tine în propriul header x-request-id sau 12 caractere hexazecimale dacă nu ai trimis niciuna. Înregistreaz-o în jurnal și menționeaz-o când ceri ajutor pentru o cerere.