Errore‑kudeaketa
Huts egiten duen eskaerak HTTP egoera-kode bat eta errore-mota eta mezu bat dituen JSON gorputz bat itzultzen ditu. Orrialde honek egoera guztiak zerrendatzen ditu, API formatu bakoitzaren errore-gorputza erakusten du eta zein erroreren kasuan merezi duen berriz bidaltzea azaltzen du.
SDK-ek egoera-kodea eta gorputzeko eremuak dituen errore-objektu bat jaurtitzen dute. Eskaera honek ez dagoen modelo bat izendatzen du:
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"}]
}' 400 egoera eta gorputz hau itzultzen ditu:
{
"error": {
"type": "invalid_request_error",
"message": "unknown model: no-such-model"
}
} Errore-gorputza
Bi gorputz daude. /v1/messages-ek Anthropic formatuan erantzuten du; beste endpoint guztiek OpenAI formatuan. Bietan, xehetasunak error.type eta error.message-en daude, beraz irakurle bakar batek endpoint guztiak zerbitzatzen ditu.
{
"error": {
"type": "authentication_error",
"message": "Invalid API key",
"code": "invalid_api_key",
"param": null
}
} {
"type": "error",
"error": {
"type": "authentication_error",
"message": "Invalid API key"
}
} | Eremua | Mota | Deskribapena |
|---|---|---|
error.type | string | Errore-mota. Ikus beheko Errore-motak. |
error.message | string | Pertsona batentzako esaldi bat. Beheko taulen testuak egonkorrak dira aldagai-zatiak izan ezik, <id>, <n> edo … gisa erakutsiak. |
error.code | string | null | OpenAI formatuko errore batzuetan dago: invalid_api_key 401-ekin, request_too_large 413-rekin, context_length_exceeded elkarrizketa luzeegia denean, bestela null edo ez dago. Erabaki lehenik egoeraren eta error.type-ren arabera, eta hartu code gehigarri gisa. |
error.param | null | code duten errore berberetan dago. Beti null. |
type | string | Anthropic formatuan bakarrik. Beti error. |
Errore-motak
| Mota | Egoerak | Deskribapena |
|---|---|---|
invalid_request_error | 400, 413, 415, 422 | Eskaera bera okerra da: eremu bat, gorputza, modelo-id-a edo modeloak hartzen ez duen sarrera. Aldatu eskaera berriro bidali aurretik. |
authentication_error | 401 | API gakoa falta da, ezezaguna da edo indargabetua da. |
not_found_error | 404 | Bidea ez dago. |
rate_limit_error | 429 | Saldoak ez du eskaera estaltzen, flood protection-ek geldiarazi du, edo modeloa okupatuta dago. Mezuak zein den esaten du. |
api_error | 500, 502, 503, 504 | Eskaera ondo zegoen eta hutsegitea gure aldean dago. Bidali berriro. |
server_error | 500 | Eskaera ondo zegoen eta hutsegitea gure aldean dago. Bidali berriro. |
Egoera-kodeak
| Egoera | Mota | Mezua | Noiz |
|---|---|---|---|
400 | invalid_request_error | Failed to parse the request body as JSON: … | Gorputza ez da JSON baliodun bat. |
400 | invalid_request_error | unknown model: <id> | model ez da argitaratutako id bat. /v1/responses endpoint-ean model falta denean ere. |
400 | invalid_request_error | No user message provided | Shannon mailak: eskaerak ez du erabiltzaile-testurik. |
400 | invalid_request_error | <id> does not accept image input | Irudi bat bidali da irudi-sarrerarik ez duen pisu irekiko modelo ostatatu batera. |
400 | invalid_request_error | audio and video input are not supported by any hosted model | Audio- edo bideo-zati bat bidali da pisu irekiko modelo ostatatu batera. |
400 | invalid_request_error | <id> does not accept response_format | Irteera egituratua eskatu zaio hura ez duen pisu irekiko modelo ostatatu bati. |
400 | invalid_request_error | <id> does not accept response_format json_schema; use json_object | JSON eskema bat bidali da json_object bakarrik hartzen duen pisu irekiko modelo ostatatu batera. |
400 | invalid_request_error | unknown reasoning effort '<value>'; expected off, low, medium or high | Arrazonamendu-esfortzua ez da zerrendatutako balioetako bat. Pisu irekiko modelo ostatatuak. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <id> | Token-kontaketa eskatu da pisu irekiko modelo ostatatuetatik kanpoko modelo baterako. |
401 | authentication_error | Missing authentication | Ez da API gakorik bidali. |
401 | authentication_error | Invalid API key | Gakoa ezezaguna da, berriago batek ordezkatu du, edo indargabetu egin da. |
404 | not_found_error | Not Found | Bidea ez dago, adibidez /v1/embeddings. |
405 | api_error | Method Not Allowed | Bidea badago baina ez HTTP metodo honekin. |
413 | invalid_request_error | Failed to buffer the request body: … | Eskaera-gorputza 32 MiB baino handiagoa da. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | Content-Type goiburua falta da edo ez da application/json. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Beharrezko eremu bat falta da, adibidez messages, edo eremu batek JSON mota okerra du. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | Eskaeraren irteera-muga zure saldoan geratzen dena baino handiagoa da. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Flood protection: minutu batean 120 eskaera baino gehiago zure kontuan. <n> minutua amaitu arteko segundo-kopurua da. |
429 | rate_limit_error | Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan | shannon-coder-1 /v1/chat/completions eta /v1/messages endpoint-etan: zure planeko Shannon Coder deiak amaitu dira uneko 4 orduko leihorako. |
429 | rate_limit_error | Shannon routes are temporarily busy. Please retry. | Modeloa okupatuta dago une honetan. |
500 | server_error | The model backend failed to answer. Please retry. | Modeloak ez du erantzunik sortu. |
500 | server_error | An internal error occurred. Please retry. | Barne-hutsegite bat eskaera prestatu bitartean. |
502 | api_error | The model backend failed to answer. Please retry. | Modeloak ez du erantzunik sortu. Shannon 3 familia eta pisu irekiko modelo ostatatuak. |
503 | api_error | Could not verify your quota right now. Please retry. | Zure saldoa ezin izan da irakurri une honetan. |
503 | api_error | token counting is temporarily unavailable for this model | Token-kontaketa ez dago eskuragarri modelo honetarako une honetan. |
504 | api_error | upstream timed out | Pisu irekiko modelo ostatatu batek stream gabeko eskaera baten denbora-muga baino gehiago behar izan du. |
Egiaztapenak ordena honetan egiten dira: API gakoa, eskaera-gorputza, modelo-id-a, flood protection, saldoa. Gako okerra eta gorputz okerra dituen eskaerak, beraz, 401 itzultzen du. 4xx egoerarekin ukatzen den eskaera ez da kobratzen.
Saldoa eta flood protection
Eskaera guztiak berdin zerbitzatzen dira: ez dago tasa-mailarik eta ez dago API kupo bereizirik. Bi gaik oraindik 429 erantzun dezakete, biak rate_limit_error motarekin. Mezuak bereizten ditu.
Saldoa
Zure saldoa gaurko planaren kupoa da, 00:00 UTC-n berrezartzen dena, eta haren ondoren erositako kreditua. Txatak eta API-ak saldo bera erabiltzen dute.
Eskaera bakoitzak lehenik bere irteera-muga bereizten du: max_tokens, edo max_output_tokens /v1/responses endpoint-ean, 4,096 bietako bat ere bidaltzen ez baduzu. Erantzuna osatzen denean, bereizitako kopurua eskaerak erabilitakoak ordezkatzen du. Kopurua geratzen den saldoan sartzen ez bada, eskaerak Quota exceeded itzultzen du modeloa hasi aurretik.
Aldi berean exekutatzen diren eskaera bakoitzak bere kopurua bereizten du. Beraz, max_tokens handia duten eskaera paralelo askok saldoa une batez agor dezakete, erantzun bakoitza laburra bada ere. max_tokens txikiago batek gutxiago bereizten du.
Flood protection
Flood protection-ek minutuko 120 eskaera onartzen ditu kontu bakoitzeko. Kontua kontatzen du, ez gakoa, /v1/chat/completions, /v1/responses eta /v1/messages batera. Minutua zure lehen eskaerarekin hasten da.
Minutu horretako 121. eskaerak Too many requests. Retry in <n>s. itzultzen du eta ez du ezer kostatzen. Ukatutako eskaerak ere kontatzen dira, beraz itxaron gabe berriz bidaltzen duen bezero bati ukatzen jarraitzen zaio minutua amaitu arte. Itxaron mezuko <n> segundoak.
Paraleloan bidalitako eskaerak ez dira paraleloak izateagatik ukatzen. Ilaran itxaroten dute eta txandaka erantzuten zaie.
GET /v1/models eta token-kontaketako endpoint-ak ez dira kontatzen.
Muga eta saldoari buruzko informazio gehiago, eta zure saldoa eta erabilera non ikusi: Mugak eta saldoa Gakoak eta erabilera
Zer berriz saiatu
Bidali eskaera berriro eskaera berak arrakasta izan dezakeenean bakarrik. OpenAI eta Anthropic SDK-ek 429 eta 5xx erantzunak bi aldiz berriro saiatzen dituzte jada beren kabuz; ezarri max_retries (maxRetries JavaScript-en) hori aldatzeko.
| Errorea | Berriz bidali? | Nola |
|---|---|---|
400, 404, 405, 413, 415, 422 | Ez. Zuzendu eskaera lehenik. | Mezuak okerra den eremua, modeloa edo sarrera izendatzen du. |
401 | Ez. Erabili baliozko gako bat. | Sortu edo ordeztu gakoa Gakoak eta erabilera orrialdean. |
429 Too many requests | Bai, itxaron ondoren. | Itxaron mezuko segundo-kopurua, eta gero bidali eskaera bera. |
429 Quota exceeded | Hala ez. | Jaitsi max_tokens, itxaron 00:00 UTC-ko eguneko berrezartzea, edo gehitu kreditua. |
429 Shannon Coder call quota reached | Bai, hurrengo leihoan. | Leihoak 4 orduz behin hasten dira 00:00 UTC-tik aurrera. Beste modelo batek berehala erantzuten du. |
429 … temporarily busy | Bai. | Itxaron segundo batzuk, eta gero gehiago saiakera bakoitzean. |
500, 502, 503 | Bai. | Itxaron segundo 1, gero 2, 4 eta 8. Gelditu saiakera batzuen ondoren eta jakinarazi eskaera-id-a. |
504 | Bai. | Bidali stream true bezala ezarrita: denbora-muga stream gabeko erantzunei aplikatzen zaie. |
Taula honi jarraitzen dion berriz saiatzeko begizta bat:
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); Stream baten barruko erroreak
Stream batek 200 egoera du lehen byte-tik. Horren ondorengo hutsegite bat streamaren barruko gertaera gisa iristen da: error kide bat duen chunk bat /v1/chat/completions endpoint-ean, error gertaera bat /v1/messages endpoint-ean, response.failed edo error gertaera bat /v1/responses endpoint-ean. Streamaren itxierako gertaerak ondoren heltzen dira oraindik. Hartu halako erantzuna huts egindakotzat eta bidali eskaera berriro, 5xx egoera batean bezala.
Modeloaren testuinguru-leihoa baino luzeagoa den elkarrizketa modu honetan jakinarazten da, invalid_request_error motarekin eta context_length_exceeded kodearekin. Laburtu elkarrizketa berriro bidali aurretik.
Frame zehatzak streamingarekin batera deskribatzen dira. Streaminga
Eskaera-id-ak
Erantzun guztiek, erroreak barne, x-request-id goiburua dute. Zure x-request-id goiburuan bidali duzun balioa da, edo 12 karaktere hexadezimal ezer bidali ez baduzu. Erregistratu, eta aipatu eskaera bati buruz laguntza eskatzen duzunean.