رفتن به محتوای اصلی

خطاها و کدهای وضعیت

ساختار پاسخ، فهرست کامل کدهای وضعیت و الگوی درست مدیریت خطا در کلاینت.


همهٔ پاسخ‌های این API — موفق یا ناموفق — ساختار یکسانی دارند، بنابراین می‌توانید یک لایهٔ مدیریت خطای واحد بنویسید و همه‌جا از آن استفاده کنید.

ساختار پاسخ

{
"return": {
"status": 200,
"message": "درخواست تایید شد."
},
"entries": []
}
  • return.status — کد وضعیت
  • return.message — پیام فارسی قابل نمایش
  • entries — داده‌های پاسخ. در پاسخ موفق یک شیء یا آرایه است و در همهٔ پاسخ‌های خطا آرایهٔ خالی [] برمی‌گردد.
کد HTTP همان return.status است

برخلاف بسیاری از APIها، این سرویس کد وضعیت داخل بدنه را در خودِ کد وضعیت HTTP هم برمی‌گرداند. مثلاً وقتی اعتبار حساب کافی نیست، پاسخ HTTP دقیقاً 418 است و return.status هم 418.

نتیجهٔ عملی: بعضی کتابخانه‌های HTTP برای کدهای غیر ۲xx استثنا پرتاب می‌کنند. کلاینت خود را طوری بنویسید که بدنهٔ پاسخ را حتی در حالت خطا هم بخواند — پیام دقیق آنجاست.

چهار استثنا که قالب بالا را ندارند

بیشتر سرویس‌ها دقیقاً همین قالب را برمی‌گردانند، ولی چهار مورد استثنا هستند و کلاینت شما باید آن‌ها را تحمل کند:

موردچه برمی‌گرداند
خطای غیرمنتظرهٔ سرورHTTP 500 با بدنهٔ {"message": "..."} — بدون return و entries
GET /health{"message": "~it works~"}
POST /v2/sms/outboxHTTP 501 با بدنهٔ {"error": "not implemented yet"}
سرویس WebEngageقالب اختصاصی {"status", "statuscode", "message"}
مورد اول روی هر سرویسی ممکن است

اگر خطای پیش‌بینی‌نشده‌ای در سرویس رخ دهد، پاسخ قالب استاندارد را ندارد. پس پیش از خواندن return، وجودش را بررسی کنید:

body = response.json()
result = body.get("return")
if result is None:
# خطای غیرمنتظرهٔ سرور — پیام در کلید "message" است
raise ServerError(body.get("message", "خطای ناشناخته"))

کدی که مستقیم body["return"]["status"] را می‌خواند، دقیقاً در بدترین لحظه (خطای سرور) با KeyError می‌شکند و پیام واقعی خطا را از دست می‌دهد.

فهرست کدهای وضعیت

این جدول فقط کدهایی را دارد که سرویس واقعاً تولید می‌کند. کدام کد از کدام سرویس برمی‌گردد، در صفحهٔ همان سرویس در بخش «پاسخ‌ها» آمده است.

موفق

کدمعنی
200درخواست تایید شد.
201ساخته شد — فقط در ساخت کمپین، بارگذاری مخاطبان و بارگذاری فایل. توجه: در این سه مورد کد HTTP برابر 201 است ولی return.status داخل بدنه 200 می‌ماند.

خطای درخواست

کدمعنی
400پارامترها ناقص هستند
411دریافت کننده نامعتبر است
412ارسال کننده نامعتبر است
414حجم درخواست بیشتر از حد مجاز است
417تاریخ ارسال اشتباه است و فرمت آن صحیح نمی‌باشد
422داده‌های ارسالی قابل پردازش نیستند (طول توکن یا قالب پارامتر در ارسال با الگو)
424تمپلیت ارسالی تایید نشده است

خطای احراز هویت و دسترسی

کدمعنی
401حساب کاربری فعال نشده است
403کد شناسائی API-Key معتبر نمی‌باشد
416IP سرویس مبدا با تنظیمات مطابقت ندارد — فقط سرویس‌های نسخهٔ ۱

خطای اعتبار و سرور

کدمعنی
418اعتبار شما کافی نمی‌باشد
500خطای داخلی رخ داده است. با پشتیبانی تماس بگیرید.
501پیاده‌سازی نشده — فقط POST /v2/sms/outbox
کدهایی که در کد تعریف شده‌اند ولی تولید نمی‌شوند

سرویس چند کد دیگر را هم در فهرست ثابت‌هایش دارد که هیچ مسیری آن‌ها را برنمی‌گرداند: 402، 404، 405، 406، 407، 409، 413، 415، 419، 420.

اگر مستندات قدیمی‌تری دیده‌اید که این کدها را وعده می‌داد، به آن‌ها تکیه نکنید. به‌طور مشخص:

  • 409 (محدودیت نرخ) — این سرویس هیچ محدودیت نرخی روی درخواست‌ها اعمال نمی‌کند.
  • 413 (طول پیام) — هیچ بررسی طول متنی روی مسیرهای ارسال انجام نمی‌شود؛ سقف «۹۰۰ کاراکتر» که در متن این کد آمده، در کد سرویس اعمال نشده است.
  • 404 و 405 — سرویس هیچ هندلر اختصاصی برای مسیر یا متد ناموجود ندارد؛ در آن حالت پاسخ متنی پیش‌فرض چارچوب برمی‌گردد، نه قالب استاندارد.

وضعیت پیامک (متفاوت با کد خطا)

مقدار status که در پاسخ سرویس‌های استعلام برای هر پیامک برمی‌گردد، ربطی به کد وضعیت درخواست ندارد. این مقدار چرخهٔ عمر یک پیامک را نشان می‌دهد:

مقدارstatustext
0دریافت کننده نامعتبر
1در صف ارسال
2زمان‌بندی شده
4ارسال شده به مخابرات
6خطا در ارسال پیام به سرشماره مشخص شده
10رسیده به گیرنده
11مشکل در رسیدن پیام
13ارسال پیام از سمت کاربر لغو شده یا در ارسال آن مشکلی پیش آمده که هزینه آن به حساب برگشت داده می‌شود
14بلاک شده است
15شماره تکراری
100شناسه پیامک نامعتبر است
وضعیت نهایی کدام‌هاست؟

10، 11، 13، 14 وضعیت‌های پایانی‌اند و دیگر تغییر نمی‌کنند. 1، 2 و 4 وضعیت‌های میانی هستند؛ برای آن‌ها استعلام را با فاصلهٔ زمانی تکرار کنید، نه در حلقهٔ تنگ.

الگوی مدیریت خطا

import requests
response = requests.post(url, json=payload, headers=headers)
body = response.json() # بدنه را در هر حالتی بخوانید
result = body.get("return")
if result is None: # خطای غیرمنتظرهٔ سرور (به هشدار بالا نگاه کنید)
raise ServerError(body.get("message", "خطای ناشناخته"))
if result["status"] == 200:
entries = body["entries"]
elif result["status"] == 418:
raise OutOfCredit(result["message"]) # اعتبار کافی نیست
elif result["status"] in (401, 403, 416):
raise AuthError(result["message"]) # کلید، حساب یا آی‌پی
elif result["status"] == 500:
retry_later() # قابل تلاش مجدد
else:
raise RequestError(result["status"], result["message"])
پیام را همان‌طور که هست نشان دهید

مقدار return.message متن فارسیِ آمادهٔ نمایش است. به‌جای نگاشت دوبارهٔ کدها به متن دلخواه خودتان، همین پیام را به کاربر نهایی نشان دهید تا با چیزی که پشتیبانی نجوا می‌بیند یکی باشد.