Ошибки и повторы
Класс исключения для каждого вида отказа и повторы, которые не могут отправить дважды.
Обработка ошибки
try { client.templates().send("order-shipped", Body.of( "from", "[email protected]", "to", "[email protected]", "props", Body.of("orderId", "AC-4192") ));} catch (ValidationException error) { System.err.println(error.param() + " " + error.getMessage());} catch (RateLimitException error) { System.err.println("Wait " + error.retryAfterSeconds() + " seconds");} catch (ApiException error) { System.err.println(error.status() + " " + error.code() + " " + error.requestId());} catch (NetworkException error) { System.err.println(error.isTimeout() ? "Timed out" : "No response");}Отказ API выбрасывает ApiException или подкласс для его типа, вместе с тем, что API о нём сообщил. Каждое исключение, которое выбрасывает клиент, является непроверяемым OpenEmailException, поэтому один catch покрывает их все.
| Метод | Что в нём |
|---|---|
| status() | HTTP-статус или 0, когда ответ не пришёл. |
| type(), code() | Тип ошибки и код API, например validation_error и invalid_parameter. |
| param() | Поле, которое виновато, если такое есть. |
| requestId() | Идентификатор, который стоит указать, когда пишете в поддержку. |
| docUrl() | Страница документации, объясняющая код. |
| retryAfterSeconds() | Сколько API попросил подождать. |
| fields() | Поля, которые отклонила форма подписки, каждое с key и error. |
| body() | Декодированное тело ответа. |
Виды сбоев
| Исключение | Когда выбрасывается |
|---|---|
| AuthenticationException | Ключ или токен отклонён, с кодом 401. |
| PermissionException | Этим учётным данным это не разрешено, с кодом 403. |
| NotFoundException | Ничего с таким идентификатором нет, с кодом 404. |
| ConflictException | Изменение противоречит текущему состоянию, с кодом 409. |
| ValidationException | Поле отклонено, с кодом 422. |
| RateLimitException | Слишком много запросов или лимит исчерпан, с кодом 429. |
| InvalidRequestException | Любой другой отказ в запросе. |
| ApiException | Сбой API, со статусом 500 или выше. |
| NetworkException | Ответ не пришёл. |
| IllegalArgumentException | Сам вызов был неверным, и ничего не было отправлено. |
| WebhookSignatureException | Доставка вебхука не прошла проверку. |
ApiException также отвечает на вопросы о себе: isValidation(), isNotFound(), isRateLimited(), isServerError() и isRetryable(), а ещё isScopeMissing(), когда учётным данным не хватает области доступа, нужной вызову, и isStepUpRequired(), когда токену доступа сначала нужно подтвердить код. NetworkException.isTimeout() сообщает, что срок истёк.
Что повторяется
- Чтения, отправки и любая запись, которую безопасно повторить, повторяются до
maxRetriesраз. Любая другая запись отправляется один раз. - Статусы 408, 500, 502, 503 и 504 повторяются с задержкой, которая начинается с половины секунды и удваивается до восьми секунд.
- 429 повторяется, только если он несёт
Retry-Afterне больше минуты, и клиент ждёт столько же. - Соединение, которое оборвалось или превысило таймаут, повторяется так же.
Повторяемая отправка каждый раз несёт один и тот же ключ идемпотентности, поэтому API воспроизводит первое сообщение, а не отправляет второе.