문서로 건너뛰기
C#

오류와 재시도

모든 거부에 하나의 예외 타입, 종류마다 하나의 속성, 그리고 두 번 보내지 않는 재시도.

오류 처리하기

errors.cs
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 필터로 종류를 고를 수 있습니다.

속성담긴 내용
StatusHTTP 상태입니다.
ErrorType, CodeAPI의 오류 타입과 코드. 예를 들어 validation_error와 invalid_parameter입니다.
Param문제가 된 필드. 있는 경우에만 들어 있습니다.
RequestId지원팀에 문의할 때 알려 줄 id입니다.
DocUrl해당 코드를 설명하는 문서 페이지입니다.
RetryAfterSecondsAPI가 기다리라고 요청한 시간(초)입니다.
Fields가입 양식이 거부한 필드. 각각 key와 error가 있습니다.
Body디코딩된 응답 본문입니다.

실패의 종류

속성true인 경우
IsAuth키 또는 토큰이 거부되었습니다. 401입니다.
IsPermission이 자격 증명으로는 할 수 없는 작업입니다. 403입니다.
IsScopeMissing호출에 필요한 스코프가 자격 증명에 없습니다.
IsStepUpRequired액세스 토큰이 먼저 코드를 인증해야 합니다.
IsNotFound해당 id를 가진 것이 없습니다. 404입니다.
IsConflict변경이 현재 상태와 충돌합니다. 409입니다.
IsValidation필드가 거부되었습니다. 422입니다.
IsRateLimited요청이 너무 많거나 할당량을 모두 썼습니다. 429입니다.
IsInvalidRequest요청에 대한 그 밖의 모든 거부입니다.
IsServerErrorAPI가 실패했습니다. 상태는 500 이상입니다.
IsRetryable클라이언트가 다시 시도하는 상태입니다.
IsTimeout타임아웃 전에 응답이 도착하지 않았습니다. 이 속성은 OpenEmailNetworkException에 있습니다.

형식이 잘못된 키나 빈 ID처럼 호출 자체의 실수는 아무것도 보내기 전에 ArgumentException을 발생시킵니다. 취소된 토큰은 OperationCanceledException을 발생시키고, 검증에 실패한 웹훅 전달은 OpenEmailWebhookException을 발생시킵니다.

인증 코드

액세스 토큰은 사용자를 대신해 동작하므로, 도메인 삭제 같은 민감한 변경 전에 웹 앱이 요구하는 것과 같은 인증 코드를 요구받습니다. 코드를 요청하고 확인한 다음 요청을 다시 보내세요. API 키는 코드를 요구받지 않습니다.

step-up.cs
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는 두 번째 메시지를 보내는 대신 첫 메시지를 재생합니다.