Перейти к документации
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, CodeТип ошибки и код API, например validation_error и invalid_parameter.
ParamПоле, которое виновато, если такое есть.
RequestIdИдентификатор, который стоит указать, когда пишете в поддержку.
DocUrlСтраница документации, объясняющая код.
RetryAfterSecondsСколько API попросил подождать, в секундах.
FieldsПоля, которые отклонила форма подписки, каждое с key и error.
BodyДекодированное тело ответа.

Виды сбоев

СвойствоКогда оно истинно
IsAuthКлюч или токен отклонён, с кодом 401.
IsPermissionЭтим учётным данным это не разрешено, с кодом 403.
IsScopeMissingУчётным данным не хватает области доступа, нужной вызову.
IsStepUpRequiredТокен доступа сначала должен подтвердить код.
IsNotFoundНичего с таким идентификатором нет, с кодом 404.
IsConflictИзменение противоречит текущему состоянию, с кодом 409.
IsValidationПоле отклонено, с кодом 422.
IsRateLimitedСлишком много запросов или лимит исчерпан, с кодом 429.
IsInvalidRequestЛюбой другой отказ в запросе.
IsServerErrorСбой API, со статусом 500 или выше.
IsRetryableСтатус относится к тем, которые клиент повторяет.
IsTimeoutОтвет не пришёл до истечения таймаута. Это свойство находится в OpenEmailNetworkException.

Ошибка в самом вызове, например неверно составленный ключ или пустой идентификатор, вызывает 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 повторяются с задержкой, которая начинается с половины секунды и удваивается до восьми секунд.
  • 429 повторяется, только если он несёт Retry-After не больше минуты, и клиент ждёт столько же.
  • Соединение, которое оборвалось или превысило таймаут, повторяется так же.

Повторяемая отправка каждый раз несёт один и тот же ключ идемпотентности, поэтому API воспроизводит первое сообщение, а не отправляет второе.