טיפול בשגיאות
בקשה שנכשלת מחזירה קוד סטטוס של 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, כך שקורא אחד משרת את כל ה-endpoints.
{
"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 | היתרה אינה מכסה את הבקשה, הגנת ההצפה עצרה אותה, או שהמודל עמוס. ההודעה אומרת מה מהם. |
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 נשלחה למודל 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. | הגנת הצפה: יותר מ-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, גוף הבקשה, מזהה המודל, הגנת הצפה, יתרה. בקשה עם מפתח שגוי וגוף שגוי מחזירה לכן 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 נמוך יותר מפריש פחות.
הגנת הצפה
הגנת הצפה מאפשרת 120 בקשות בדקה לחשבון. היא סופרת את החשבון, לא את המפתח, על /v1/chat/completions, /v1/responses ו-/v1/messages יחד. הדקה מתחילה עם הבקשה הראשונה שלכם.
בקשה מספר 121 בתוך אותה דקה מחזירה Too many requests. Retry in <n>s. ואינה עולה כלום. גם בקשות שנדחו נספרות, ולכן לקוח ששולח שוב בלי להמתין ממשיך להידחות עד שהדקה נגמרת. המתינו את <n> השניות מההודעה.
בקשות שנשלחות במקביל אינן נדחות בגלל שהן במקביל. הן ממתינות בתור ונענות בזו אחר זו.
GET /v1/models וה-endpoints לספירת טוקנים אינם נספרים.
עוד על מגבלות ויתרה, ואיפה רואים את היתרה והשימוש שלכם: מגבלות ויתרה מפתחות ושימוש
מה לנסות שוב
שלחו בקשה שוב רק כשאותה בקשה יכולה להצליח. ה-SDK של OpenAI ושל Anthropic כבר מנסים שוב תשובות 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); שגיאות בתוך stream
ל-stream יש סטטוס 200 מהבייט הראשון שלו. כשל אחרי כן מגיע כאירוע בתוך ה-stream: chunk עם איבר error ב-/v1/chat/completions, אירוע error ב-/v1/messages, אירוע response.failed או error ב-/v1/responses. אירועי הסיום של ה-stream עדיין באים אחריו. התייחסו לתשובה כזו ככושלת ושלחו את הבקשה שוב, כמו בסטטוס 5xx.
שיחה ארוכה מחלון ההקשר של המודל מדווחת כך, עם הסוג invalid_request_error והקוד context_length_exceeded. קצרו את השיחה לפני שאתם שולחים שוב.
הפריימים המדויקים מתוארים בנושא streaming. הזרמה
מזהי בקשה
לכל תשובה, כולל שגיאות, יש כותרת x-request-id. זה הערך ששלחתם בכותרת x-request-id שלכם, או 12 תווים הקסדצימליים כששלחתם ערך. תעדו אותו, וציינו אותו כשאתם מבקשים עזרה בנוגע לבקשה.