דילוג לתוכן
טיפול בשגיאות

טיפול בשגיאות

בקשה שנכשלת מחזירה קוד סטטוס של 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

היא מחזירה סטטוס 400 ואת הגוף הזה:

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

גוף השגיאה

יש שני גופים. /v1/messages עונה בפורמט Anthropic; כל endpoint אחר עונה בפורמט OpenAI. בשניהם הפרטים נמצאים ב-error.type וב-error.message, כך שקורא אחד משרת את כל ה-endpoints.

401 פורמט OpenAI
{
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key",
    "code": "invalid_api_key",
    "param": null
  }
}
401 פורמט Anthropic
{
  "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)

שגיאות בתוך 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 תווים הקסדצימליים כששלחתם ערך. תעדו אותו, וציינו אותו כשאתם מבקשים עזרה בנוגע לבקשה.