C#
오류와 재시도
모든 거부에 하나의 예외 타입, 종류마다 하나의 속성, 그리고 두 번 보내지 않는 재시도.
오류 처리하기
try{ await client.Emails.SendAsync(new Body { ["from"] = "[email protected]", ["to"] = "[email protected]", ["subject"] = "Your September invoice", ["text"] = "Invoice attached.", });}catch (OpenEmailApiException error) when (error.IsValidation){ Console.Error.WriteLine($"{error.Code} {error.Param} {error.Message}");}catch (OpenEmailApiException error) when (error.IsRateLimited){ Console.Error.WriteLine($"try again in {error.RetryAfterSeconds} seconds");}catch (OpenEmailNetworkException error) when (error.IsTimeout){ Console.Error.WriteLine("no answer in time");}API의 거부는 OpenEmailApiException을 발생시키고, 응답이 전혀 없으면 OpenEmailNetworkException을 발생시킵니다. 둘 다 OpenEmailException에서 파생되므로 하나의 catch로 둘 다 잡을 수 있고, when 필터로 종류를 고를 수 있습니다.
| 속성 | 담긴 내용 |
|---|---|
| Status | HTTP 상태입니다. |
| ErrorType, Code | API의 오류 타입과 코드. 예를 들어 validation_error와 invalid_parameter입니다. |
| Param | 문제가 된 필드. 있는 경우에만 들어 있습니다. |
| RequestId | 지원팀에 문의할 때 알려 줄 id입니다. |
| DocUrl | 해당 코드를 설명하는 문서 페이지입니다. |
| RetryAfterSeconds | API가 기다리라고 요청한 시간(초)입니다. |
| Fields | 가입 양식이 거부한 필드. 각각 key와 error가 있습니다. |
| Body | 디코딩된 응답 본문입니다. |
실패의 종류
| 속성 | true인 경우 |
|---|---|
| IsAuth | 키 또는 토큰이 거부되었습니다. 401입니다. |
| IsPermission | 이 자격 증명으로는 할 수 없는 작업입니다. 403입니다. |
| IsScopeMissing | 호출에 필요한 스코프가 자격 증명에 없습니다. |
| IsStepUpRequired | 액세스 토큰이 먼저 코드를 인증해야 합니다. |
| IsNotFound | 해당 id를 가진 것이 없습니다. 404입니다. |
| IsConflict | 변경이 현재 상태와 충돌합니다. 409입니다. |
| IsValidation | 필드가 거부되었습니다. 422입니다. |
| IsRateLimited | 요청이 너무 많거나 할당량을 모두 썼습니다. 429입니다. |
| IsInvalidRequest | 요청에 대한 그 밖의 모든 거부입니다. |
| IsServerError | API가 실패했습니다. 상태는 500 이상입니다. |
| IsRetryable | 클라이언트가 다시 시도하는 상태입니다. |
| IsTimeout | 타임아웃 전에 응답이 도착하지 않았습니다. 이 속성은 OpenEmailNetworkException에 있습니다. |
형식이 잘못된 키나 빈 ID처럼 호출 자체의 실수는 아무것도 보내기 전에 ArgumentException을 발생시킵니다. 취소된 토큰은 OperationCanceledException을 발생시키고, 검증에 실패한 웹훅 전달은 OpenEmailWebhookException을 발생시킵니다.
인증 코드
액세스 토큰은 사용자를 대신해 동작하므로, 도메인 삭제 같은 민감한 변경 전에 웹 앱이 요구하는 것과 같은 인증 코드를 요구받습니다. 코드를 요청하고 확인한 다음 요청을 다시 보내세요. API 키는 코드를 요구받지 않습니다.
var domainId = "b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f"; try{ await client.Domains.DeleteAsync(domainId);}catch (OpenEmailApiException error) when (error.IsStepUpRequired){ var challenge = await client.Security.BeginStepUpAsync(); Console.WriteLine($"Enter the code sent by {challenge["method"]}"); await client.Security.VerifyStepUpAsync(new Body { ["code"] = Console.ReadLine()?.Trim() }); await client.Domains.DeleteAsync(domainId);}다시 시도되는 것
- 읽기, 발송, 그리고 반복해도 안전한 모든 쓰기는 최대
MaxRetries번까지 다시 시도됩니다. 그 밖의 쓰기는 한 번만 보냅니다. - 상태 408, 500, 502, 503, 504는 0.5초에서 시작해 8초까지 두 배씩 늘어나는 대기 시간을 두고 다시 시도됩니다.
- 429는 1분 이하의
Retry-After가 있을 때만 다시 시도되며, 클라이언트는 그 시간만큼 기다립니다. - 실패하거나 타임아웃된 연결도 같은 방식으로 다시 시도됩니다.
다시 시도되는 발송은 매번 같은 멱등성 키를 가지므로, API는 두 번째 메시지를 보내는 대신 첫 메시지를 재생합니다.