Preskoči na sadržaj
Upravljanje greškama

Upravljanje greškama

Zahtjev koji ne uspije vraća HTTP statusni kod i JSON tijelo s tipom greške i porukom. Ova stranica navodi svaki status, prikazuje tijelo greške svakog API formata i kaže koje je greške vrijedno ponoviti.

SDK-ovi podižu objekat greške koji nosi statusni kod i polja tijela. Ovaj zahtjev navodi model koji ne postoji:

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

Vraća status 400 i ovo tijelo:

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

Tijelo greške

Postoje dva tijela. /v1/messages odgovara u Anthropic formatu; svaki drugi endpoint odgovara u OpenAI formatu. U oba, detalji su u error.type i error.message, pa jedan čitač služi svim endpointima.

401 OpenAI format
{
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key",
    "code": "invalid_api_key",
    "param": null
  }
}
401 Anthropic format
{
  "type": "error",
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key"
  }
}
Polje Tip Opis
error.type string Vrsta greške. Pogledajte Tipovi grešaka u nastavku.
error.message string Rečenica za čovjeka. Tekstovi u tabelama ispod su stabilni do svojih promjenjivih dijelova, prikazanih kao <id>, <n> ili ….
error.code string | null Prisutno na nekim greškama OpenAI formata: invalid_api_key uz 401, request_too_large uz 413, context_length_exceeded kada je razgovor predug, inače null ili odsutno. Prvo odlučujte na osnovu statusa i error.type, a code tretirajte kao dodatak.
error.param null Prisutno na istim greškama kao code. Uvijek null.
type string Samo Anthropic format. Uvijek error.

Tipovi grešaka

Tip Statusi Opis
invalid_request_error 400, 413, 415, 422 Sam zahtjev je pogrešan: polje, tijelo, id modela ili ulaz koji model ne prima. Promijenite zahtjev prije nego što ga ponovo pošaljete.
authentication_error 401 API ključ nedostaje, nepoznat je ili opozvan.
not_found_error 404 Putanja ne postoji.
rate_limit_error 429 Stanje ne pokriva zahtjev, flood zaštita ga je zaustavila ili je model zauzet. Poruka kaže šta je od toga.
api_error 500, 502, 503, 504 Zahtjev je bio ispravan, a greška je na našoj strani. Pošaljite ga ponovo.
server_error 500 Zahtjev je bio ispravan, a greška je na našoj strani. Pošaljite ga ponovo.

Statusni kodovi

Status Tip Poruka Kada
400 invalid_request_error Failed to parse the request body as JSON: … Tijelo nije valjan JSON.
400 invalid_request_error unknown model: <id> model nije objavljeni id. Na /v1/responses i kada model nedostaje.
400 invalid_request_error No user message provided Shannon nivoi: zahtjev ne sadrži korisnički tekst.
400 invalid_request_error <id> does not accept image input Slika je poslana hostiranom open-weight modelu bez ulaza slike.
400 invalid_request_error audio and video input are not supported by any hosted model Audio ili video dio poslan je hostiranom open-weight modelu.
400 invalid_request_error <id> does not accept response_format Strukturirani izlaz zatražen je od hostiranog open-weight modela koji ga nema.
400 invalid_request_error <id> does not accept response_format json_schema; use json_object JSON šema je poslana hostiranom open-weight modelu koji prima samo json_object.
400 invalid_request_error unknown reasoning effort '<value>'; expected off, low, medium or high Reasoning effort nije jedna od navedenih vrijednosti. Hostirani open-weight modeli.
400 invalid_request_error count_tokens is available for the hosted open models; unknown model: <id> Brojanje tokena zatraženo je za model izvan hostiranih open-weight modela.
401 authentication_error Missing authentication API ključ nije poslan.
401 authentication_error Invalid API key Ključ je nepoznat, zamijenjen je novijim ili je opozvan.
404 not_found_error Not Found Putanja ne postoji, na primjer /v1/embeddings.
405 api_error Method Not Allowed Putanja postoji, ali ne s ovom HTTP metodom.
413 invalid_request_error Failed to buffer the request body: … Tijelo zahtjeva je veće od 32 MiB.
415 invalid_request_error Expected request with `Content-Type: application/json` Zaglavlje Content-Type nedostaje ili nije application/json.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … Obavezno polje nedostaje, kao što je messages, ili polje ima pogrešan JSON tip.
429 rate_limit_error Quota exceeded. Upgrade your plan at shannon-ai.com/plan Ograničenje izlaza zahtjeva veće je od onoga što je preostalo na vašem stanju.
429 rate_limit_error Too many requests. Retry in <n>s. Flood zaštita: više od 120 zahtjeva u jednoj minuti na vašem računu. <n> je broj sekundi do kraja minute.
429 rate_limit_error Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan shannon-coder-1 na /v1/chat/completions i /v1/messages: Shannon Coder pozivi vašeg plana za trenutni 4-satni prozor su potrošeni.
429 rate_limit_error Shannon routes are temporarily busy. Please retry. Model je trenutno zauzet.
500 server_error The model backend failed to answer. Please retry. Model nije dao odgovor.
500 server_error An internal error occurred. Please retry. Interni kvar dok se zahtjev pripremao.
502 api_error The model backend failed to answer. Please retry. Model nije dao odgovor. Porodica Shannon 3 i hostirani open-weight modeli.
503 api_error Could not verify your quota right now. Please retry. Vaše stanje trenutno nije moguće pročitati.
503 api_error token counting is temporarily unavailable for this model Brojanje tokena trenutno nije dostupno za ovaj model.
504 api_error upstream timed out Hostirani open-weight model trajao je duže od vremenskog ograničenja za zahtjev bez streama.

Provjere se izvršavaju ovim redoslijedom: API ključ, tijelo zahtjeva, id modela, flood zaštita, stanje. Zahtjev s pogrešnim ključem i pogrešnim tijelom stoga vraća 401. Zahtjev koji se odbije statusom 4xx ne naplaćuje se.

Stanje i flood zaštita

Svaki zahtjev se poslužuje jednako: nema nivoa ograničenja protoka i nema zasebne API kvote. Ipak, dvije stvari mogu odgovoriti s 429, obje s tipom rate_limit_error. Poruka ih razlikuje.

Stanje

Vaše stanje je današnja kvota plana, koja se resetuje u 00:00 UTC, a nakon nje vaš kupljeni kredit. Chat i API crpe iz istog stanja.

Svaki zahtjev prvo odvaja svoje ograničenje izlaza: max_tokens, ili max_output_tokens na /v1/responses, 4,096 kada ne pošaljete nijedno. Kada je odgovor završen, odvojeni iznos se zamjenjuje onim što je zahtjev iskoristio. Ako se iznos ne uklapa u preostalo stanje, zahtjev vraća Quota exceeded prije nego što model počne.

Zahtjevi koji se izvršavaju istovremeno odvajaju svaki svoj iznos. Mnogo paralelnih zahtjeva s visokim max_tokens stoga može načas iscrpiti stanje, čak i kada je svaki odgovor kratak. Manji max_tokens odvaja manje.

Flood zaštita

Flood zaštita dozvoljava 120 zahtjeva u minuti po računu. Broji račun, a ne ključ, preko /v1/chat/completions, /v1/responses i /v1/messages zajedno. Minuta počinje vašim prvim zahtjevom.

Zahtjev broj 121 unutar te minute vraća Too many requests. Retry in <n>s. i ne košta ništa. Odbijeni zahtjevi se također broje, pa klijent koji ponovo šalje bez čekanja ostaje odbijen dok minuta ne istekne. Sačekajte <n> sekundi iz poruke.

Zahtjevi poslani paralelno ne odbijaju se zbog toga što su paralelni. Čekaju u redu i dobijaju odgovor redom.

GET /v1/models i endpointi za brojanje tokena se ne broje.

Više o ograničenjima i stanju, te gdje vidjeti vlastito stanje i korištenje: Ograničenja i stanje Ključevi i korištenje

Šta ponoviti

Zahtjev šaljite ponovo samo kada isti zahtjev može uspjeti. OpenAI i Anthropic SDK-ovi već sami dvaput ponavljaju odgovore 429 i 5xx; postavite max_retries (maxRetries u JavaScriptu) da to promijenite.

Greška Poslati ponovo? Kako
400, 404, 405, 413, 415, 422 Ne. Prvo ispravite zahtjev. Poruka imenuje polje, model ili ulaz koji je pogrešan.
401 Ne. Koristite važeći ključ. Kreirajte ili zamijenite ključ na stranici Ključevi i korištenje.
429 Too many requests Da, nakon čekanja. Sačekajte broj sekundi iz poruke, zatim pošaljite isti zahtjev.
429 Quota exceeded Ne u ovom obliku. Smanjite max_tokens, pričekajte dnevni reset u 00:00 UTC ili dodajte kredit.
429 Shannon Coder call quota reached Da, u sljedećem prozoru. Prozori počinju svaka 4 sata od 00:00 UTC. Drugi model odgovara odmah.
429 … temporarily busy Da. Sačekajte nekoliko sekundi, zatim duže pri svakom daljem pokušaju.
500, 502, 503 Da. Sačekajte 1 sekundu, zatim 2, 4 i 8. Stanite nakon nekoliko pokušaja i prijavite id zahtjeva.
504 Da. Pošaljite ga sa stream postavljenim na true: vremensko ograničenje vrijedi za odgovore koji nisu streamovani.

Petlja ponavljanja koja prati ovu tabelu:

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)

Greške unutar streama

Stream ima status 200 od prvog bajta. Greška nakon toga stiže kao događaj unutar streama: chunk s članom error na /v1/chat/completions, događaj error na /v1/messages, događaj response.failed ili error na /v1/responses. Završni događaji streama ipak slijede. Takav odgovor smatrajte neuspjelim i pošaljite zahtjev ponovo, kao za status 5xx.

Razgovor duži od kontekstnog prozora modela prijavljuje se na ovaj način, s tipom invalid_request_error i kodom context_length_exceeded. Skratite razgovor prije nego što ga ponovo pošaljete.

Tačni frameovi opisani su uz streaming. Streaming

Idovi zahtjeva

Svaki odgovor, uključujući greške, ima zaglavlje x-request-id. To je vrijednost koju ste poslali u svom zaglavlju x-request-id, ili 12 heksadecimalnih znakova kada niste poslali nijednu. Zabilježite je i navedite kada tražite pomoć oko zahtjeva.