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