문서로 건너뛰기
Python

오류

모든 실패는 예외를 발생시킵니다. 클래스는 두 가지이며, 모든 API 오류에는 요청 id가 담깁니다.

오류 잡기

catch_errors.py
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()로 확인해 출력하는 이유가 여기에 있습니다.

클래스

클래스발생 조건
OpenEmailApiErrorAPI가 응답했지만 성공이 아니었습니다. message, status, type, code, param, doc_url, request_id, retry_after_seconds, fields, body를 담고 있습니다.
OpenEmailNetworkError응답이 전혀 오지 않았습니다. DNS, TLS, 끊긴 연결, 타임아웃 때문입니다. 그 밑에 있는 httpx 예외를 cause에 담으며, 타임아웃이 원인이면 is_timeout이 True입니다.
OpenEmailError둘의 기반 클래스이므로, except 하나로 API나 네트워크 때문에 생긴 모든 실패를 잡을 수 있습니다. verify_webhook_signature가 발생시키는 WebhookVerificationError도 이 클래스를 상속합니다.
ValueError아무것도 전송되기 전에 발생합니다. 키가 없거나 형식이 잘못된 경우, 사용할 수 없는 base_url, 암호화되지 않은 http로 보내질 자격 증명, 빈 id가 여기에 해당합니다. 잘못된 http_client나 JSON으로 담을 수 없는 본문은 대신 TypeError를 발생시킵니다.

fields는 가입 양식이 거부한 각 답변을 key와 error로 나열하며, 그 밖의 모든 오류에서는 None입니다. body는 API가 보낸 JSON을 담고 있으며, 본문이 JSON이 아니었다면 None입니다.

속성true가 되는 조건
is_authtype이 authentication_error인 401입니다. 키가 없거나, 자격 증명의 종류가 잘못되었거나, OpenEmail이 발급하지 않은 키입니다.
is_permissionpermission_error, 즉 403입니다. 유효한 키이지만 필요한 스코프나 From 주소를 갖고 있지 않습니다.
is_scope_missingcode가 insufficient_scope인 경우로, 빠진 스코프를 명시하는 403입니다.
is_invalid_requestinvalid_request_error, 즉 400입니다. 해석할 수 없는 요청입니다. 크기 상한을 넘은 메시지는 422 message_too_large로 돌아오므로, 그 경우를 잡는 속성은 is_validation입니다.
is_validationvalidation_error, 즉 422입니다. 스키마가 요청을 거부했으며 param이 해당 필드를 가리킵니다.
is_not_foundnot_found_error, 즉 404입니다. 그런 리소스가 없습니다.
is_conflictconflict_error, 즉 409입니다. 리소스가 이미 이 작업을 할 수 있는 시점을 지났습니다.
is_rate_limitedrate_limit_error, 즉 429입니다. 서버가 대기 시간을 지정한 경우 retry_after_seconds에 그 값이 담깁니다.
is_server_errorstatus가 500 이상입니다. 지원팀에 문의할 때는 request_id를 함께 알려 주십시오.
is_retryablestatus가 408, 429, 500, 502, 503, 504 중 하나입니다.
is_step_up_requiredcode가 step_up_required인 경우로, 사용자가 코드를 인증하기 전까지 OAuth 액세스 토큰이 민감한 변경 전에 받는 403입니다.

대부분의 속성은 오류 봉투에서 고정된 쪽인 type을 읽습니다. code는 API가 개방적이고 추가만 된다고 보장하는 값이므로 str로 남아 있으며, 알아보지 못하는 값은 그 type으로 취급하십시오. 닫힌 Literal로 만들면 새로운 실패 모드를 읽는 대가로 SDK를 업그레이드해야 합니다.

API의 오류 봉투 형식이 아닌 본문도 여전히 OpenEmailApiError가 되며, type은 상태 코드에서 추론하고 code는 unrecognised_response로 설정됩니다. 본문이 JSON이 아닌 성공 응답도 마찬가지로 이 예외를 발생시킵니다.

AsyncOpenEmail 호출을 취소해도 OpenEmailError는 발생하지 않습니다. 요청 도중이든 재시도 전 대기 중이든 취소 자체가 그대로 전파되며, 그 뒤에는 아무것도 재시도되지 않습니다.

request_id

모든 OpenEmailApiError는 서버가 보낸 요청 id를 오류 본문이나 x-request-id 헤더에서 가져와 담고 있으며, 이 값만이 여러분의 실패를 서버 로그의 한 줄과 이어 줍니다. 성공하면 파싱된 본문만 반환되므로 거기서 읽을 요청 id는 없습니다.

str(error)는 상태 코드, 오류 코드, 요청 id로 끝나므로, 예외를 출력하는 로그 줄에는 세 가지가 모두 남습니다. OpenEmailApiError는 모든 필드를 유지한 채 pickle할 수 있어서, 워커 프로세스에서 발생한 예외도 부모 프로세스에 온전히 전달됩니다.