Ракување со грешки
Барање што не успева враќа HTTP статус код и JSON тело со тип на грешка и порака. Оваа страница го наведува секој статус, го прикажува телото на грешка на секој API формат и кажува кои грешки вреди да се испратат повторно.
SDK-ата подигнуваат објект на грешка што го носи статус кодот и полињата од телото. Ова барање именува модел што не постои:
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 и ова тело:
{
"error": {
"type": "invalid_request_error",
"message": "unknown model: no-such-model"
}
} Тело на грешка
Постојат две тела. /v1/messages одговара во Anthropic форматот; секој друг endpoint одговара во OpenAI форматот. Во двата, деталите се во error.type и error.message, па еден читач служи за сите endpoint-и.
{
"error": {
"type": "authentication_error",
"message": "Invalid API key",
"code": "invalid_api_key",
"param": null
}
} {
"type": "error",
"error": {
"type": "authentication_error",
"message": "Invalid API key"
}
} | Поле | Тип | Опис |
|---|---|---|
error.type | string | Видот на грешката. Видете Типови грешки подолу. |
error.message | string | Реченица за човек. Текстовите во табелите подолу се стабилни освен нивните променливи делови, прикажани како <id>, <n> или …. |
error.code | string | null | Присутно на некои грешки во OpenAI форматот: invalid_api_key со 401, request_too_large со 413, context_length_exceeded кога разговорот е предолг, инаку null или отсутно. Прво одлучувајте според статусот и error.type, а code третирајте го како додаток. |
error.param | null | Присутно на истите грешки како code. Секогаш null. |
type | string | Само во Anthropic форматот. Секогаш error. |
Типови грешки
| Тип | Статуси | Опис |
|---|---|---|
invalid_request_error | 400, 413, 415, 422 | Самото барање е погрешно: поле, тело, ид на модел или влез што моделот не го прима. Променете го барањето пред да го испратите повторно. |
authentication_error | 401 | API клучот недостасува, непознат е или е отповикан. |
not_found_error | 404 | Патеката не постои. |
rate_limit_error | 429 | Салдото не го покрива барањето, flood protection го запрел или моделот е зафатен. Пораката кажува кое од тоа. |
api_error | 500, 502, 503, 504 | Барањето било во ред, а неуспехот е на наша страна. Испратете го повторно. |
server_error | 500 | Барањето било во ред, а неуспехот е на наша страна. Испратете го повторно. |
Статус кодови
| Статус | Тип | Порака | Кога |
|---|---|---|---|
400 | invalid_request_error | Failed to parse the request body as JSON: … | Телото не е важечки JSON. |
400 | invalid_request_error | unknown model: <id> | model не е објавен ид. На /v1/responses и кога model недостасува. |
400 | invalid_request_error | No user message provided | Нивоа на Shannon: барањето не содржи кориснички текст. |
400 | invalid_request_error | <id> does not accept image input | Слика е испратена до хостиран open-weight модел без слика на влез. |
400 | invalid_request_error | audio and video input are not supported by any hosted model | Аудио или видео дел е испратен до хостиран open-weight модел. |
400 | invalid_request_error | <id> does not accept response_format | Структуриран излез е побаран од хостиран open-weight модел што го нема. |
400 | invalid_request_error | <id> does not accept response_format json_schema; use json_object | JSON schema е испратена до хостиран open-weight модел што прима само json_object. |
400 | invalid_request_error | unknown reasoning effort '<value>'; expected off, low, medium or high | Напорот на reasoning не е една од наведените вредности. Хостирани open-weight модели. |
400 | invalid_request_error | count_tokens is available for the hosted open models; unknown model: <id> | Броење токени е побарано за модел надвор од хостираните open-weight модели. |
401 | authentication_error | Missing authentication | Не е испратен API клуч. |
401 | authentication_error | Invalid API key | Клучот е непознат, заменет е со понов или е отповикан. |
404 | not_found_error | Not Found | Патеката не постои, на пример /v1/embeddings. |
405 | api_error | Method Not Allowed | Патеката постои, но не со овој HTTP метод. |
413 | invalid_request_error | Failed to buffer the request body: … | Телото на барањето е поголемо од 32 MiB. |
415 | invalid_request_error | Expected request with `Content-Type: application/json` | Заглавието Content-Type недостасува или не е application/json. |
422 | invalid_request_error | Failed to deserialize the JSON body into the target type: … | Задолжително поле недостасува, како messages, или некое поле има погрешен JSON тип. |
429 | rate_limit_error | Quota exceeded. Upgrade your plan at shannon-ai.com/plan | Границата за излез на барањето е поголема од тоа што остана од вашето салдо. |
429 | rate_limit_error | Too many requests. Retry in <n>s. | Flood protection: повеќе од 120 барања во една минута на вашата сметка. <n> е бројот секунди до крајот на минутата. |
429 | rate_limit_error | Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan | shannon-coder-1 на /v1/chat/completions и /v1/messages: повиците на Shannon Coder од вашиот план за тековниот 4-часовен прозорец се искористени. |
429 | rate_limit_error | Shannon routes are temporarily busy. Please retry. | Моделот е зафатен во овој момент. |
500 | server_error | The model backend failed to answer. Please retry. | Моделот не даде одговор. |
500 | server_error | An internal error occurred. Please retry. | Внатрешен неуспех додека барањето се подготвувало. |
502 | api_error | The model backend failed to answer. Please retry. | Моделот не даде одговор. Семејството Shannon 3 и хостираните open-weight модели. |
503 | api_error | Could not verify your quota right now. Please retry. | Вашето салдо не можеше да се прочита во овој момент. |
503 | api_error | token counting is temporarily unavailable for this model | Броењето токени не е достапно за овој модел во овој момент. |
504 | api_error | upstream timed out | Хостиран open-weight модел потрошил повеќе од временската граница на барање без streaming. |
Проверките се извршуваат по овој редослед: API клуч, тело на барање, ид на модел, flood protection, салдо. Барање со погрешен клуч и погрешно тело затоа враќа 401. Барање одбиено со статус 4xx не се наплатува.
Салдо и заштита од преплавување
Секое барање се опслужува еднакво: нема нивоа на стапка и нема посебна API квота. Две работи сепак можат да одговорат со 429, и двете со типот rate_limit_error. Пораката ги разликува.
Салдо
Вашето салдо е дневниот лимит од планот, кој се обновува во 00:00 UTC, а по него купениот кредит. Разговорот и API-то црпат од истото салдо.
Секое барање прво ја одвојува својата граница за излез: max_tokens, или max_output_tokens на /v1/responses, 4,096 кога не испраќате ниту едно. Кога одговорот е готов, одвоената количина се заменува со тоа што барањето го употребило. Ако количината не собира во преостанатото салдо, барањето враќа Quota exceeded пред моделот да започне.
Барањата што се извршуваат истовремено секое одвојува своја количина. Многу паралелни барања со високо max_tokens затоа можат накратко да го потрошат салдото, дури и кога секој одговор е краток. Пониско max_tokens одвојува помалку.
Flood protection
Flood protection дозволува 120 барања во минута по сметка. Ја брои сметката, а не клучот, преку /v1/chat/completions, /v1/responses и /v1/messages заедно. Минутата започнува со вашето прво барање.
Барањето број 121 во таа минута враќа Too many requests. Retry in <n>s. и не чини ништо. Одбиените барања се бројат исто така, па клиент што испраќа повторно без да чека останува одбиен додека не помине минутата. Почекајте ги <n> секундите од пораката.
Барања испратени паралелно не се одбиваат поради тоа што се паралелни. Чекаат на ред и им се одговара по ред.
GET /v1/models и endpoint-ите за броење токени не се бројат.
Повеќе за лимитите и салдото, и каде да го видите вашето салдо и употреба: Ограничувања и салдо Клучеви и употреба
Што да се повтори
Испратете барање повторно само кога истото барање може да успее. OpenAI и Anthropic SDK-ата веќе самите повторуваат одговори 429 и 5xx двапати; поставете max_retries (maxRetries во JavaScript) за да го промените тоа.
| Грешка | Да се испрати повторно? | Како |
|---|---|---|
400, 404, 405, 413, 415, 422 | Не. Прво поправете го барањето. | Пораката го именува полето, моделот или влезот што е погрешен. |
401 | Не. Користете важечки клуч. | Креирајте или заменете го клучот на страницата Клучеви и употреба. |
429 Too many requests | Да, по чекањето. | Почекајте го бројот секунди од пораката, па испратете го истото барање. |
429 Quota exceeded | Не онака како што е. | Намалете max_tokens, почекајте го дневното обновување во 00:00 UTC или додадете кредит. |
429 Shannon Coder call quota reached | Да, во следниот прозорец. | Прозорците започнуваат на секои 4 часа од 00:00 UTC. Друг модел одговара веднаш. |
429 … temporarily busy | Да. | Почекајте неколку секунди, па подолго при секој следен обид. |
500, 502, 503 | Да. | Почекајте 1 секунда, потоа 2, 4 и 8. Запрете по неколку обиди и пријавете го ид-то на барањето. |
504 | Да. | Испратете го со stream поставено на true: временската граница важи за одговори без streaming. |
Циклус за повторување што ја следи оваа табела:
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); Грешки во streaming
Streaming има статус 200 од својот прв бајт. Неуспех по тоа пристигнува како настан во streaming-от: дел со член error на /v1/chat/completions, настан error на /v1/messages, настан response.failed или error на /v1/responses. Завршните настани на streaming-от сепак следуваат. Третирајте таков одговор како неуспешен и испратете го барањето повторно, како за статус 5xx.
Разговор подолг од контекстниот прозорец на моделот се пријавува на овој начин, со типот invalid_request_error и кодот context_length_exceeded. Скратете го разговорот пред да го испратите повторно.
Точните фрејмови се опишани заедно со streaming. Стриминг
ID-а на барања
Секој одговор, вклучувајќи ги и грешките, има заглавие x-request-id. Тоа е вредноста што сте ја испратиле во вашето заглавие x-request-id, или 12 хексадецимални знаци кога не сте испратиле. Запишете го и наведете го кога барате помош за барање.