خطاها
هر شکستی raise میشود. دو کلاس، و یک شناسهٔ درخواست روی هر خطای API.
گرفتن یک خطا
from openemail import OpenEmailApiError, OpenEmailNetworkError, openemail try: openemail.emails.send({'from': sender, 'to': recipient, 'subject': subject, 'text': text})except OpenEmailApiError as error: if error.is_validation: print(error.code, error.param, error.message) if error.is_permission: print(openemail.addresses.list()) if error.is_rate_limited: print('try again in', error.retry_after_seconds, 'seconds') print(error.status, error.request_id) raiseexcept OpenEmailNetworkError as error: if error.is_timeout: print('no answer in time') raiseیک permission_error روی ارسال معمولاً به اسکوپ ارسالِ خودِ کلید برمیگردد، به دامنه یا آدرسی که به آن داده نشده، نه به فضای کاری؛ و به همین دلیل است که نمونه چاپ میکند addresses.list() میگوید این کلید از چه آدرسهایی میتواند بفرستد.
کلاسها
| کلاس | چه زمانی |
|---|---|
| OpenEmailApiError | API پاسخ داده است، اما نه با موفقیت. حامل message، status، type، code، param، doc_url، request_id، retry_after_seconds، fields و body است. |
| OpenEmailNetworkError | هیچ پاسخی نرسیده است: DNS، TLS، قطع شدن اتصال یا تایماوت. حامل cause است، یعنی استثنای httpx زیرین، و وقتی دلیل، تایماوت بوده باشد is_timeout برابر True است. |
| OpenEmailError | پایهٔ هر دو، پس یک except هر شکستی را که API یا شبکه سبب شده باشد میگیرد. WebhookVerificationError هم، که verify_webhook_signature آن را raise میکند، از آن ارث میبرد. |
| ValueError | پیش از فرستادن هر چیزی raise میشود: کلیدی که نیست یا بدشکل است، base_url ای که به کار نمیآید، اعتبارنامهای که راهی http ساده است، یک id خالی. یک http_client نادرست، یا بدنهای که JSON نمیتواند حملش کند، بهجای آن TypeError را raise میکند. |
fields هر پاسخی را که یک فرم ثبتنام رد کرده، بهصورت key و error فهرست میکند، و روی هر خطای دیگری None است. body همان JSON ای را که API فرستاده نگه میدارد، یا وقتی بدنه JSON نبوده None است.
| ویژگی | چه زمانی true است |
|---|---|
| is_auth | type برابر authentication_error است، یک 401 Unauthorized: نبودن کلید، نوع نادرست اعتبارنامه، یا کلیدی که ما صادرش نکردهایم. |
| is_permission | permission_error، یک 403 Forbidden: کلیدی واقعی بدون اسکوپ یا بدون آدرس From مورد نیازش. |
| is_scope_missing | code برابر insufficient_scope است، همان 403 Forbidden که اسکوپ غایب را نام میبرد. |
| is_invalid_request | invalid_request_error، یک 400: درخواستی که قابل فهم نبوده است. پیامی فراتر از سقف اندازه بهصورت 422 با message_too_large برمیگردد، پس is_validation ویژگیای است که آن را میگیرد. |
| is_validation | validation_error، یک 422: اسکیما آن را نپذیرفته است و param نام فیلد را میگوید. |
| is_not_found | not_found_error، یک 404 Not Found: چنین منبعی وجود ندارد. |
| is_conflict | conflict_error، یک 409 Conflict: منبع از نقطهای گذشته است که بتوان این کار را روی آن انجام داد. |
| is_rate_limited | rate_limit_error، یک 429 Too Many Requests. وقتی سرور مدتی را نام برده باشد، retry_after_seconds آن انتظار را نگه میدارد. |
| is_server_error | status برابر 500 یا بالاتر است. اگر با پشتیبانی تماس گرفتید، request_id را ذکر کنید. |
| is_retryable | status یکی از 408، 429، 500، 502، 503 یا 504 است. |
| is_step_up_required | code برابر step_up_required است: همان 403 که توکن دسترسی OAuth پیش از یک تغییر حساس میگیرد تا وقتی شخص کدی را تأیید کند. |
بیشتر ویژگیها type را میخوانند، یعنی نیمهٔ ثابتِ پاکت. code یک str باقی میماند، چون API تضمین میکند که باز و افزایشی است؛ پس کدی را که نمیشناسید مطابق type آن رفتار کنید. یک Literal بسته، بهای خواندن یک حالت شکست تازه را به ارتقای SDK تبدیل میکرد.
بدنهای که پاکت خطای API نباشد باز هم به OpenEmailApiError تبدیل میشود، با type استنتاجشده از status و code برابر unrecognised_response. پاسخ موفقی که بدنهاش JSON نباشد نیز همین خطا را raise میکند.
لغو یک فراخوانی AsyncOpenEmail هیچ OpenEmailError ای raise نمیکند. خودِ لغو منتشر میشود، چه در میانهٔ درخواست رخ دهد چه در انتظار پیش از یک تلاش دوباره، و پس از آن هیچ چیزی دوباره تلاش نمیشود.
request_id
هر OpenEmailApiError شناسهٔ درخواستی را که سرور فرستاده است با خود دارد، از بدنهٔ خطا یا از هدر x-request-id، و تنها چیزی است که شکست شما را به یک سطر در لاگ سرور گره میزند. یک پاسخ موفق تنها بدنهٔ تجزیهشده را برمیگرداند، پس روی آن شناسهٔ درخواستی برای خواندن وجود ندارد.
str(error) با status، کد و شناسهٔ درخواست تمام میشود، پس سطری از لاگ که استثنا را چاپ میکند هر سه را نگه میدارد. یک OpenEmailApiError با همهٔ فیلدهایش از pickle شدن هم سالم بیرون میآید، پس خطایی که در یک پردازهٔ worker raise شود دستنخورده به پردازهٔ والد میرسد.