Feilhåndtering
En forespørsel som mislykkes, returnerer en HTTP-statuskode og en JSON-kropp med en feiltype og en melding. Denne siden lister alle statuser, viser feilkroppen i hvert API-format og forteller hvilke feil det er verdt å sende på nytt.
SDK-ene kaster et feilobjekt som har statuskoden og feltene fra kroppen. Denne forespørselen oppgir en modell som ikke finnes:
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 import OpenAI from "openai";
const client = new OpenAI({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com/v1",
});
try {
await client.chat.completions.create({
model: "no-such-model",
messages: [{ role: "user", content: "Hello" }],
});
} catch (error) {
if (!(error instanceof OpenAI.APIError)) throw error;
console.log(error.status); // 400
console.log(error.type); // invalid_request_error
console.log(error.error.message); // unknown model: no-such-model
} curl -i https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "no-such-model",
"messages": [{"role": "user", "content": "Hello"}]
}' Den returnerer status 400 og denne kroppen:
{
"error": {
"type": "invalid_request_error",
"message": "unknown model: no-such-model"
}
} Feilkropp
Det finnes to kropper. /v1/messages svarer i Anthropic-formatet; alle andre endepunkter svarer i OpenAI-formatet. I begge ligger detaljene i error.type og error.message, så én leser dekker alle endepunkter.
{
"error": {
"type": "authentication_error",
"message": "Invalid API key",
"code": "invalid_api_key",
"param": null
}
} {
"type": "error",
"error": {
"type": "authentication_error",
"message": "Invalid API key"
}
} | Felt | Type | Beskrivelse |
|---|---|---|
error.type | string | Typen feil. Se Feiltyper nedenfor. |
error.message | string | En setning for et menneske. Tekstene i tabellene nedenfor er stabile bortsett fra de variable delene, vist som <id>, <n> eller …. |
error.code | string | null | Finnes på noen feil i OpenAI-formatet: invalid_api_key med 401, request_too_large med 413, context_length_exceeded når en samtale er for lang, ellers null eller fraværende. Avgjør først etter status og error.type, og behandle code som et tillegg. |
error.param | null | Finnes på de samme feilene som code. Alltid null. |
type | string | Bare Anthropic-formatet. Alltid error. |
Feiltyper
| Type | Statuser | Beskrivelse |
|---|---|---|
invalid_request_error | 400, 413, 415, 422 | Selve forespørselen er feil: et felt, kroppen, modell-id-en eller en input modellen ikke tar. Endre forespørselen før du sender den på nytt. |
authentication_error | 401 | API-nøkkelen mangler, er ukjent eller er tilbakekalt. |
not_found_error | 404 | Stien finnes ikke. |
rate_limit_error | 429 | Saldoen dekker ikke forespørselen, flood protection stoppet den, eller modellen er opptatt. Meldingen sier hvilket. |
api_error | 500, 502, 503, 504 | Forespørselen var i orden, og feilen ligger hos oss. Send den på nytt. |
server_error | 500 | Forespørselen var i orden, og feilen ligger hos oss. Send den på nytt. |
Statuskoder
| Status | Type | Melding | Når |
|---|---|---|---|
400 | invalid_request_error | Failed to parse the request body as JSON: … | Kroppen er ikke gyldig JSON. |
400 | invalid_request_error | unknown model: <id> | model er ikke en publisert id. På /v1/responses også når model mangler. |
400 | invalid_request_error | No user message provided | Shannon-nivåer: forespørselen har ingen brukertekst. |
400 | invalid_request_error | <id> does not accept image input | Et bilde ble sendt til en hostet åpen vektmodell uten støtte for bilde som input. |
400 | invalid_request_error | audio and video input are not supported by any hosted model | En lyd- eller videodel ble sendt til en hostet åpen vektmodell. |
400 | invalid_request_error | <id> does not accept response_format | Strukturert output ble etterspurt fra en hostet åpen vektmodell som ikke har det. |
400 | invalid_request_error | <id> does not accept response_format json_schema; use json_object | Et JSON-skjema ble sendt til en hostet åpen vektmodell som bare tar json_object. |
400 | invalid_request_error | unknown reasoning effort '<value>'; expected off, low, medium or high | Resonneringsinnsatsen er ikke en av de oppførte verdiene. Hostede åpne vektmodeller. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <id> | Token-telling ble etterspurt for en modell utenfor de hostede åpne vektmodellene. |
401 | authentication_error | Missing authentication | Ingen API-nøkkel ble sendt. |
401 | authentication_error | Invalid API key | Nøkkelen er ukjent, ble erstattet av en nyere, eller ble tilbakekalt. |
404 | not_found_error | Not Found | Stien finnes ikke, for eksempel /v1/embeddings. |
405 | api_error | Method Not Allowed | Stien finnes, men ikke med denne HTTP-metoden. |
413 | invalid_request_error | Failed to buffer the request body: … | Forespørselskroppen er større enn 32 MiB. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | Headeren Content-Type mangler eller er ikke application/json. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Et påkrevd felt mangler, for eksempel messages, eller et felt har feil JSON-type. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | Output-grensen i forespørselen er større enn det som er igjen av saldoen din. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Flood protection: mer enn 120 forespørsler i løpet av ett minutt på kontoen din. <n> er antall sekunder til minuttet er over. |
429 | rate_limit_error | Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan | shannon-coder-1 på /v1/chat/completions og /v1/messages: Shannon Coder-kallene i planen din for gjeldende 4-timersvindu er brukt. |
429 | rate_limit_error | Shannon routes are temporarily busy. Please retry. | Modellen er opptatt akkurat nå. |
500 | server_error | The model backend failed to answer. Please retry. | Modellen ga ikke noe svar. |
500 | server_error | An internal error occurred. Please retry. | En intern feil mens forespørselen ble forberedt. |
502 | api_error | The model backend failed to answer. Please retry. | Modellen ga ikke noe svar. Shannon 3-familien og hostede åpne vektmodeller. |
503 | api_error | Could not verify your quota right now. Please retry. | Saldoen din kunne ikke leses akkurat nå. |
503 | api_error | token counting is temporarily unavailable for this model | Token-telling er ikke tilgjengelig for denne modellen akkurat nå. |
504 | api_error | upstream timed out | En hostet åpen vektmodell brukte lengre tid enn tidsgrensen for en forespørsel uten strømming. |
Sjekkene kjøres i denne rekkefølgen: API-nøkkel, forespørselskropp, modell-id, flood protection, saldo. En forespørsel med feil nøkkel og feil kropp returnerer derfor 401. En forespørsel som avvises med en 4xx-status, belastes ikke.
Saldo og flood protection
Hver forespørsel betjenes likt: det finnes ingen rate-nivåer og ingen separat API-kvote. To ting kan likevel gi 429, begge med typen rate_limit_error. Meldingen skiller dem fra hverandre.
Saldo
Saldoen din er dagens plan-kvote, som nullstilles kl. 00:00 UTC, og deretter den kjøpte kreditten din. Chat og API trekker fra den samme saldoen.
Hver forespørsel setter først av output-grensen sin: max_tokens, eller max_output_tokens på /v1/responses, 4,096 når du ikke sender noen av dem. Når svaret er fullført, erstattes det avsatte beløpet av det forespørselen brukte. Hvis beløpet ikke får plass i saldoen som er igjen, returnerer forespørselen Quota exceeded før modellen starter.
Forespørsler som kjører samtidig, setter hver av sitt eget beløp. Mange parallelle forespørsler med høy max_tokens kan derfor tømme saldoen for en stund, selv om hvert svar er kort. En lavere max_tokens setter av mindre.
Flood protection
Flood protection tillater 120 forespørsler per minutt per konto. Den teller kontoen, ikke nøkkelen, over /v1/chat/completions, /v1/responses og /v1/messages samlet. Minuttet starter med den første forespørselen din.
Forespørsel nummer 121 innenfor det minuttet returnerer Too many requests. Retry in <n>s. og koster ingenting. Avviste forespørsler telles også, så en klient som sender på nytt uten å vente, forblir avvist til minuttet er over. Vent de <n> sekundene fra meldingen.
Forespørsler som sendes parallelt, avvises ikke for å være parallelle. De venter i kø og besvares etter tur.
GET /v1/models og endepunktene for token-telling telles ikke.
Mer om grenser og saldo, og hvor du ser din egen saldo og bruk: Grenser og saldo Nøkler og bruk
Hva som kan prøves på nytt
Send en forespørsel på nytt bare når den samme forespørselen kan lykkes. OpenAI- og Anthropic-SDK-ene prøver allerede 429- og 5xx-svar på nytt to ganger på egen hånd; sett max_retries (maxRetries i JavaScript) for å endre det.
| Feil | Sende på nytt? | Hvordan |
|---|---|---|
400, 404, 405, 413, 415, 422 | Nei. Rett forespørselen først. | Meldingen nevner feltet, modellen eller inputen som er feil. |
401 | Nei. Bruk en gyldig nøkkel. | Opprett eller bytt nøkkelen på siden Nøkler og bruk. |
429 Too many requests | Ja, etter ventetiden. | Vent antall sekunder som står i meldingen, og send så den samme forespørselen. |
429 Quota exceeded | Ikke som den er. | Senk max_tokens, vent på den daglige nullstillingen kl. 00:00 UTC, eller fyll på kreditt. |
429 Shannon Coder call quota reached | Ja, i neste vindu. | Vinduene starter hver 4. time fra kl. 00:00 UTC. En annen modell svarer med en gang. |
429 … temporarily busy | Ja. | Vent noen sekunder, deretter lenger for hvert nye forsøk. |
500, 502, 503 | Ja. | Vent 1 sekund, deretter 2, 4 og 8. Stopp etter noen få forsøk og rapporter forespørsels-id-en. |
504 | Ja. | Send den med stream satt til true: tidsgrensen gjelder svar uten strømming. |
En retry-sløyfe som følger denne tabellen:
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) import OpenAI from "openai";
// maxRetries: 0 — this loop does the retrying, the SDK does not add its own.
const client = new OpenAI({ apiKey: "YOUR_API_KEY", baseURL: "https://api.shannon-ai.com/v1", maxRetries: 0 });
const sleep = (seconds) => new Promise((resolve) => setTimeout(resolve, seconds * 1000));
async function createWithRetry(request, attempts = 5) {
for (let attempt = 0; attempt < attempts; attempt++) {
try {
return await client.chat.completions.create(request);
} catch (error) {
const text = String(error.message);
const flood = text.match(/Retry in (\d+)s/);
if (error.status === 429 && flood) {
await sleep(Number(flood[1])); // flood protection: wait out the minute
} else if (error.status === 429 && text.includes("temporarily busy")) {
await sleep(2 ** attempt);
} else if (error.status >= 500 || error instanceof OpenAI.APIConnectionError) {
await sleep(2 ** attempt); // 1, 2, 4, 8 seconds
} else {
throw error; // wrong request, wrong key or balance
}
}
}
throw new Error("the request failed after all attempts");
}
const response = await createWithRetry({
model: "shannon-3",
messages: [{ role: "user", content: "Hello" }],
});
console.log(response.choices[0].message.content); Feil inne i en strøm
En strøm har status 200 fra første byte. En feil etter det kommer som en hendelse inne i strømmen: en chunk med et error-medlem på /v1/chat/completions, en error-hendelse på /v1/messages, en response.failed- eller error-hendelse på /v1/responses. De avsluttende hendelsene i strømmen kommer likevel etterpå. Behandle et slikt svar som mislykket og send forespørselen på nytt, som for en 5xx-status.
En samtale som er lengre enn modellens kontekstvindu, rapporteres på denne måten, med typen invalid_request_error og koden context_length_exceeded. Forkort samtalen før du sender den på nytt.
De nøyaktige rammene er beskrevet under strømming. Strømming
Forespørsels-id-er
Hvert svar, også feil, har en x-request-id-header. Den er verdien du sendte i din egen x-request-id-header, eller 12 heksadesimale tegn hvis du ikke sendte noen. Logg den, og oppgi den når du ber om hjelp med en forespørsel.