Java
오류와 재시도
거부 종류마다 하나의 예외 클래스, 그리고 두 번 보내지 않는 재시도.
오류 처리하기
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() | 지원팀에 문의할 때 알려 줄 id입니다. |
| docUrl() | 해당 코드를 설명하는 문서 페이지입니다. |
| retryAfterSeconds() | API가 기다리라고 요청한 시간입니다. |
| fields() | 가입 양식이 거부한 필드. 각각 key와 error가 있습니다. |
| body() | 디코딩된 응답 본문입니다. |
실패의 종류
| 예외 | 던져지는 경우 |
|---|---|
| AuthenticationException | 키 또는 토큰이 거부되었습니다. 401입니다. |
| PermissionException | 이 자격 증명으로는 할 수 없는 작업입니다. 403입니다. |
| NotFoundException | 해당 id를 가진 것이 없습니다. 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는 0.5초에서 시작해 8초까지 두 배씩 늘어나는 대기 시간을 두고 다시 시도됩니다.
- 429는 1분 이하의
Retry-After가 있을 때만 다시 시도되며, 클라이언트는 그 시간만큼 기다립니다. - 실패하거나 타임아웃된 연결도 같은 방식으로 다시 시도됩니다.
다시 시도되는 발송은 매번 같은 멱등성 키를 가지므로, API는 두 번째 메시지를 보내는 대신 첫 메시지를 재생합니다.