-
-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
Key Problem
Different GOAWAY error codes require different handling strategies:
// Current: Cannot distinguish between these scenarios
try {
client.send(request, BodyHandlers.ofString());
} catch (IOException e) {
// Was it NO_ERROR (safe retry) or ENHANCE_YOUR_CALM (backoff needed)?
// Was it PROTOCOL_ERROR (client bug) or REFUSED_STREAM (retry OK)?
}
// Proposed: Explicit error code handling
catch (HttpGoAwayException e) {
switch (e.getErrorCode()) {
case NO_ERROR: retryImmediately(); break;
case ENHANCE_YOUR_CALM: exponentialBackoff(); break;
case PROTOCOL_ERROR: reportBug(); break;
}
}Establishes foundation for future HttpGoAwayException implementation, following precedent of HttpTimeoutException and HttpConnectTimeoutException.
See GOAWAY.md for a more complete elaboration and JavaHttpClientGoawayTest for a testcase
java-http-client/src/test/java/io/github/laeubi/httpclient/JavaHttpClientGoawayTest.java
Lines 35 to 70 in db99114
| @Test | |
| @DisplayName("HTTP/2 GOAWAY can be handled") | |
| public void testHttp2GoawayIsHandled() throws Exception { | |
| logger.info("\n=== Testing HTTP/2 GOAWAY ==="); | |
| HttpClient client = httpsClient(); | |
| HttpRequest request = HttpRequest.newBuilder().uri(getHttpsUrl()).GET().build(); | |
| logger.info("Sending HTTP request to " + getHttpsUrl()); | |
| CompletableFuture<HttpResponse<String>> responseAsync = client.sendAsync(request, | |
| HttpResponse.BodyHandlers.ofString()); | |
| try { | |
| responseAsync.join(); | |
| } catch (Exception e) { | |
| // whatever happens, we just want to make sure the request is complete | |
| logger.info("Caught exception during join: " + e); | |
| } | |
| httpsServer.assertGoaway(); | |
| try { | |
| HttpResponse<String> response = responseAsync.get(); | |
| logger.info("Response status: {}", response.statusCode()); | |
| logger.info("Response version: {}", response.version()); | |
| logger.info("Response body: {}", response.body()); | |
| logger.info("Response headers: {}", response.headers().map()); | |
| assertEquals(200, response.statusCode(), "Expected 200 OK response"); | |
| assertNotNull(response.body(), "Response body should not be null"); | |
| logger.info("=== HTTP/2 Upgrade test completed successfully ===\n"); | |
| } catch (ExecutionException e) { | |
| Throwable cause = e.getCause(); | |
| cause.printStackTrace(); | |
| // Here we have no way to know any of the details of the GOAWAY see GOAWAY.md | |
| // for further rationale. | |
| assertNotEquals(IOException.class, cause.getClass()); | |
| } | |
| } |