Erros e novas tentativas
Uma classe de exceção para cada género de recusa e novas tentativas que não podem enviar duas vezes.
Tratar um erro
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");}Uma recusa da API lança uma ApiException, ou a subclasse do seu tipo, com o que a API disse sobre ela. Todas as exceções que o cliente lança são uma OpenEmailException não verificada, por isso um só catch cobre-as todas.
| Método | O que contém |
|---|---|
| status() | O estado HTTP, ou 0 quando não chegou nenhuma resposta. |
| type(), code() | O tipo de erro e o código da API, como validation_error e invalid_parameter. |
| param() | O campo responsável, quando existe. |
| requestId() | O id a indicar quando escrever ao suporte. |
| docUrl() | A página da documentação que explica o código. |
| retryAfterSeconds() | Quanto tempo a API lhe pediu para esperar. |
| fields() | Os campos que um formulário de inscrição recusou, cada um com uma key e um error. |
| body() | O corpo da resposta, descodificado. |
Os géneros de falha
| Exceção | Quando é lançada |
|---|---|
| AuthenticationException | A chave ou o token foi recusado, com um 401. |
| PermissionException | A credencial não pode fazer isto, com um 403. |
| NotFoundException | Nada tem esse id, com um 404. |
| ConflictException | A alteração entra em conflito com o estado atual, com um 409. |
| ValidationException | Um campo foi recusado, com um 422. |
| RateLimitException | Demasiados pedidos, ou uma quota esgotou-se, com um 429. |
| InvalidRequestException | Qualquer outra recusa do pedido. |
| ApiException | A API falhou, com um estado de 500 ou superior. |
| NetworkException | Não chegou nenhuma resposta. |
| IllegalArgumentException | A própria chamada estava errada, e nada foi enviado. |
| WebhookSignatureException | Uma entrega de webhook falhou na sua verificação. |
Uma ApiException também responde a perguntas sobre si própria: isValidation(), isNotFound(), isRateLimited(), isServerError() e isRetryable(), com isScopeMissing() quando falta à credencial o âmbito de que a chamada precisa e isStepUpRequired() quando um token de acesso tem primeiro de verificar um código. NetworkException.isTimeout() diz que o prazo passou.
O que é tentado de novo
- As leituras, os envios e todas as escritas que é seguro repetir são tentados de novo, até
maxRetriesvezes. Qualquer outra escrita é enviada uma só vez. - Os estados 408, 500, 502, 503 e 504 são tentados de novo com uma espera que começa em meio segundo e duplica até oito segundos.
- Um 429 só é tentado de novo quando traz um
Retry-Afterde um minuto ou menos, e o cliente espera esse tempo. - Uma ligação que falha ou que excede o tempo limite é tentada de novo da mesma forma.
Um envio tentado de novo leva sempre a mesma chave de idempotência, por isso a API repete a primeira mensagem em vez de enviar uma segunda.