কনটেন্টে যান
এরর হ্যান্ডলিং

এরর হ্যান্ডলিং

ব্যর্থ রিকোয়েস্ট একটি 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 ফরম্যাটে উত্তর দেয়; বাকি সব এন্ডপয়েন্ট OpenAI ফরম্যাটে। দুটোতেই বিবরণ থাকে error.type ও error.message-এ, তাই একটি রিডারই সব এন্ডপয়েন্টের জন্য যথেষ্ট।

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 ফরম্যাটের কিছু এররে থাকে: 401-এর সাথে invalid_api_key, 413-এর সাথে request_too_large, কথোপকথন বেশি দীর্ঘ হলে context_length_exceeded, অন্যথায় null বা অনুপস্থিত। আগে স্ট্যাটাস ও error.type দেখে সিদ্ধান্ত নিন, code-কে বাড়তি তথ্য হিসেবে ধরুন।
error.param null code-এর মতো একই এররগুলোতে থাকে। সবসময় null।
type string শুধু Anthropic ফরম্যাটে। সবসময় error।

এররের ধরন

টাইপ স্ট্যাটাস বিবরণ
invalid_request_error 400, 413, 415, 422 রিকোয়েস্টটিই ভুল: কোনো ফিল্ড, বডি, মডেল id, বা মডেল নেয় না এমন ইনপুট। আবার পাঠানোর আগে রিকোয়েস্ট বদলান।
authentication_error 401 API key নেই, অজানা, বা বাতিল করা হয়েছে।
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 কোনো প্রকাশিত id নয়। /v1/responses-এ model না থাকলেও এটি হয়।
400 invalid_request_error No user message provided Shannon টিয়ার: রিকোয়েস্টে ব্যবহারকারীর কোনো টেক্সট নেই।
400 invalid_request_error <id> does not accept image input ইমেজ ইনপুট নেই এমন একটি হোস্টেড ওপেন-ওয়েট মডেলকে ইমেজ পাঠানো হয়েছে।
400 invalid_request_error audio and video input are not supported by any hosted model একটি হোস্টেড ওপেন-ওয়েট মডেলকে অডিও বা ভিডিও অংশ পাঠানো হয়েছে।
400 invalid_request_error <id> does not accept response_format স্ট্রাকচার্ড আউটপুট নেই এমন একটি হোস্টেড ওপেন-ওয়েট মডেলের কাছে তা চাওয়া হয়েছে।
400 invalid_request_error <id> does not accept response_format json_schema; use json_object শুধু json_object নেয় এমন একটি হোস্টেড ওপেন-ওয়েট মডেলকে JSON schema পাঠানো হয়েছে।
400 invalid_request_error unknown reasoning effort '<value>'; expected off, low, medium or high রিজনিং এফোর্ট তালিকার মানগুলোর কোনোটি নয়। হোস্টেড ওপেন-ওয়েট মডেল।
400 invalid_request_error count_tokens is available for the hosted open models; unknown model: <id> হোস্টেড ওপেন-ওয়েট মডেলের বাইরের কোনো মডেলের জন্য token গণনা চাওয়া হয়েছে।
401 authentication_error Missing authentication কোনো API key পাঠানো হয়নি।
401 authentication_error Invalid API key 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 type ভুল।
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 /v1/chat/completions ও /v1/messages-এ shannon-coder-1: বর্তমান 4 ঘণ্টার উইন্ডোর জন্য আপনার প্ল্যানের Shannon Coder কল শেষ।
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 পরিবার ও হোস্টেড ওপেন-ওয়েট মডেল।
503 api_error Could not verify your quota right now. Please retry. এই মুহূর্তে আপনার ব্যালেন্স পড়া যায়নি।
503 api_error token counting is temporarily unavailable for this model এই মুহূর্তে এই মডেলের জন্য token গণনা পাওয়া যাচ্ছে না।
504 api_error upstream timed out স্ট্রিম না করা রিকোয়েস্টের সময়সীমার চেয়ে বেশি সময় নিয়েছে একটি হোস্টেড ওপেন-ওয়েট মডেল।

যাচাই এই ক্রমে চলে: API key, রিকোয়েস্ট বডি, মডেল id, ফ্লাড প্রোটেকশন, ব্যালেন্স। তাই ভুল key ও ভুল বডিসহ রিকোয়েস্ট 401 ফেরত দেয়। 4xx স্ট্যাটাসে প্রত্যাখ্যাত রিকোয়েস্টে চার্জ হয় না।

ব্যালেন্স ও ফ্লাড প্রোটেকশন

প্রতিটি রিকোয়েস্ট সমানভাবে সরবরাহ করা হয়: কোনো রেট টিয়ার নেই এবং আলাদা API কোটা নেই। তবু দুটি কারণে 429 আসতে পারে, দুটোতেই type rate_limit_error। বার্তা দেখে আলাদা করা যায়।

ব্যালেন্স

আপনার ব্যালেন্স হলো আজকের প্ল্যান এলাউন্স, যা 00:00 UTC-তে রিসেট হয়, এবং তারপর আপনার কেনা ক্রেডিট। চ্যাট ও API একই ব্যালেন্স থেকে খরচ করে।

প্রতিটি রিকোয়েস্ট প্রথমে নিজের আউটপুট সীমা আলাদা করে রাখে: max_tokens, অথবা /v1/responses-এ max_output_tokens, কোনোটিই না দিলে 4,096। উত্তর সম্পূর্ণ হলে আলাদা করা পরিমাণ রিকোয়েস্টের প্রকৃত ব্যবহারে বদলে যায়। পরিমাণটি অবশিষ্ট ব্যালেন্সে না ধরলে মডেল শুরু হওয়ার আগেই রিকোয়েস্ট Quota exceeded ফেরত দেয়।

একই সময়ে চলা রিকোয়েস্টগুলো প্রত্যেকে নিজের পরিমাণ আলাদা করে রাখে। তাই বড় max_tokens সহ অনেক সমান্তরাল রিকোয়েস্ট প্রতিটি উত্তর ছোট হলেও কিছুক্ষণের জন্য ব্যালেন্স ফুরিয়ে দিতে পারে। ছোট max_tokens কম আলাদা করে রাখে।

ফ্লাড প্রোটেকশন

ফ্লাড প্রোটেকশনে প্রতি অ্যাকাউন্টে প্রতি মিনিটে 120টি রিকোয়েস্ট চলে। এটি key নয়, অ্যাকাউন্ট ধরে গোনে, এবং /v1/chat/completions, /v1/responses ও /v1/messages একসাথে ধরে। মিনিট শুরু হয় আপনার প্রথম রিকোয়েস্ট থেকে।

ওই মিনিটের মধ্যে 121 নম্বর রিকোয়েস্ট Too many requests. Retry in <n>s. ফেরত দেয় এবং কোনো খরচ হয় না। প্রত্যাখ্যাত রিকোয়েস্টও গণনায় ধরা হয়, তাই অপেক্ষা না করে আবার পাঠানো ক্লায়েন্ট মিনিট শেষ না হওয়া পর্যন্ত প্রত্যাখ্যাত হতে থাকে। বার্তায় দেওয়া <n> সেকেন্ড অপেক্ষা করুন।

সমান্তরালে পাঠানো রিকোয়েস্ট সমান্তরাল বলে প্রত্যাখ্যাত হয় না। সেগুলো সারিতে অপেক্ষা করে এবং পালাক্রমে উত্তর পায়।

GET /v1/models এবং token গণনার এন্ডপয়েন্টগুলো গণনায় ধরা হয় না।

লিমিট ও ব্যালেন্স সম্পর্কে আরও, এবং নিজের ব্যালেন্স ও ব্যবহার কোথায় দেখবেন: সীমা ও ব্যালেন্স Keys & usage

কোনগুলো আবার চেষ্টা করবেন

একই রিকোয়েস্ট সফল হতে পারলেই কেবল আবার পাঠান। OpenAI ও Anthropic SDK নিজে থেকেই 429 ও 5xx উত্তরে দুবার পুনরায় চেষ্টা করে; তা বদলাতে max_retries (JavaScript-এ maxRetries) সেট করুন।

এরর আবার পাঠাবেন? কীভাবে
400, 404, 405, 413, 415, 422 না। আগে রিকোয়েস্ট ঠিক করুন। বার্তায় ভুল ফিল্ড, মডেল বা ইনপুটের নাম থাকে।
401 না। বৈধ key ব্যবহার করুন। Keys & usage পেজে key তৈরি করুন বা বদলান।
429 Too many requests হ্যাঁ, অপেক্ষার পর। বার্তায় দেওয়া সেকেন্ড সংখ্যা অপেক্ষা করুন, তারপর একই রিকোয়েস্ট পাঠান।
429 Quota exceeded যেমন আছে তেমন নয়। max_tokens কমান, 00:00 UTC-তে দৈনিক রিসেটের জন্য অপেক্ষা করুন, অথবা ক্রেডিট যোগ করুন।
429 Shannon Coder call quota reached হ্যাঁ, পরবর্তী উইন্ডোতে। উইন্ডো 00:00 UTC থেকে প্রতি 4 ঘণ্টায় শুরু হয়। অন্য মডেল সাথে সাথে উত্তর দেয়।
429 … temporarily busy হ্যাঁ। কয়েক সেকেন্ড অপেক্ষা করুন, প্রতিবার আরও বেশি সময় অপেক্ষা করুন।
500, 502, 503 হ্যাঁ। 1 সেকেন্ড অপেক্ষা করুন, তারপর 2, 4 ও 8। কয়েকবার চেষ্টার পর থামুন এবং রিকোয়েস্ট id জানান।
504 হ্যাঁ। stream কে true করে পাঠান: সময়সীমা শুধু স্ট্রিম না করা উত্তরের ক্ষেত্রে প্রযোজ্য।

এই টেবিল মেনে চলা একটি রিট্রাই লুপ:

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)

স্ট্রিমের ভেতরের এরর

স্ট্রিমের স্ট্যাটাস প্রথম বাইট থেকেই 200। এরপর কোনো ব্যর্থতা এলে তা স্ট্রিমের ভেতরে ইভেন্ট হিসেবে আসে: /v1/chat/completions-এ error সদস্যসহ একটি চাঙ্ক, /v1/messages-এ একটি error ইভেন্ট, /v1/responses-এ একটি response.failed বা error ইভেন্ট। স্ট্রিমের সমাপ্তি ইভেন্টগুলো তারপরও আসে। এমন উত্তরকে ব্যর্থ ধরুন এবং 5xx স্ট্যাটাসের মতো রিকোয়েস্ট আবার পাঠান।

মডেলের কনটেক্সট উইন্ডোর চেয়ে দীর্ঘ কথোপকথন এভাবে জানানো হয়, type invalid_request_error ও code context_length_exceeded সহ। আবার পাঠানোর আগে কথোপকথন ছোট করুন।

সঠিক ফ্রেমগুলো স্ট্রিমিং পেজে বর্ণিত আছে। স্ট্রিমিং

রিকোয়েস্ট id

প্রতিটি উত্তরে, এররসহ, একটি x-request-id হেডার থাকে। এটি আপনার নিজের পাঠানো x-request-id হেডারের মান, না পাঠালে 12টি হেক্সাডেসিমাল অক্ষর। এটি লগ করুন, এবং কোনো রিকোয়েস্ট নিয়ে সাহায্য চাইলে উল্লেখ করুন।