Skip to content

Commit f518ed0

Browse files
authored
Merge pull request #275 from avaje/SentryMan-decoder
[http-client] Exception Mapper/Async Retry (2)
2 parents ae8aadd + 3a16ecb commit f518ed0

File tree

21 files changed

+354
-291
lines changed

21 files changed

+354
-291
lines changed

http-client/src/main/java/io/avaje/http/client/DBaseBuilder.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.List;
1616
import java.util.Optional;
1717
import java.util.concurrent.Executor;
18+
import java.util.function.Function;
1819

1920
import static java.util.Objects.requireNonNull;
2021

@@ -27,6 +28,7 @@ abstract class DBaseBuilder {
2728
Duration requestTimeout = Duration.ofSeconds(20);
2829
BodyAdapter bodyAdapter;
2930
RetryHandler retryHandler;
31+
Function<HttpException, RuntimeException> errorHandler;
3032
AuthTokenProvider authTokenProvider;
3133

3234
CookieHandler cookieHandler = new CookieManager();
@@ -167,7 +169,15 @@ DHttpClientContext buildClient() {
167169
if (bodyAdapter == null) {
168170
bodyAdapter = defaultBodyAdapter();
169171
}
170-
return new DHttpClientContext(client, baseUrl, requestTimeout, bodyAdapter, retryHandler, buildListener(), authTokenProvider, buildIntercept());
172+
return new DHttpClientContext(
173+
client,
174+
baseUrl,
175+
requestTimeout,
176+
bodyAdapter,
177+
retryHandler,
178+
errorHandler,
179+
buildListener(),
180+
authTokenProvider,
181+
buildIntercept());
171182
}
172-
173183
}

http-client/src/main/java/io/avaje/http/client/DHttpClientBuilder.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.time.Duration;
1111
import java.util.Collections;
1212
import java.util.concurrent.Executor;
13+
import java.util.function.Function;
1314

1415
final class DHttpClientBuilder extends DBaseBuilder implements HttpClient.Builder, HttpClient.Builder.State {
1516

@@ -52,6 +53,12 @@ public HttpClient.Builder retryHandler(RetryHandler retryHandler) {
5253
return this;
5354
}
5455

56+
@Override
57+
public HttpClient.Builder globalErrorMapper(Function<HttpException, RuntimeException> handler) {
58+
this.errorHandler = handler;
59+
return this;
60+
}
61+
5562
@Override
5663
public HttpClient.Builder requestLogging(boolean requestLogging) {
5764
this.requestLogging = requestLogging;

http-client/src/main/java/io/avaje/http/client/DHttpClientContext.java

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.util.concurrent.atomic.AtomicReference;
1515
import java.util.concurrent.atomic.LongAccumulator;
1616
import java.util.concurrent.atomic.LongAdder;
17+
import java.util.function.Function;
1718

1819
final class DHttpClientContext implements HttpClient, SpiHttpClient {
1920

@@ -39,21 +40,31 @@ final class DHttpClientContext implements HttpClient, SpiHttpClient {
3940
private final LongAdder metricResBytes = new LongAdder();
4041
private final LongAdder metricResMicros = new LongAdder();
4142
private final LongAccumulator metricResMaxMicros = new LongAccumulator(Math::max, 0);
42-
43-
DHttpClientContext(java.net.http.HttpClient httpClient, String baseUrl, Duration requestTimeout, BodyAdapter bodyAdapter, RetryHandler retryHandler, RequestListener requestListener, AuthTokenProvider authTokenProvider, RequestIntercept intercept) {
43+
private final Function<HttpException, RuntimeException> errorHandler;
44+
45+
DHttpClientContext(
46+
java.net.http.HttpClient httpClient,
47+
String baseUrl,
48+
Duration requestTimeout,
49+
BodyAdapter bodyAdapter,
50+
RetryHandler retryHandler,
51+
Function<HttpException, RuntimeException> errorHandler,
52+
RequestListener requestListener,
53+
AuthTokenProvider authTokenProvider,
54+
RequestIntercept intercept) {
4455
this.httpClient = httpClient;
4556
this.baseUrl = baseUrl;
4657
this.requestTimeout = requestTimeout;
4758
this.bodyAdapter = bodyAdapter;
4859
this.retryHandler = retryHandler;
60+
this.errorHandler = errorHandler;
4961
this.requestListener = requestListener;
5062
this.authTokenProvider = authTokenProvider;
5163
this.withAuthToken = authTokenProvider != null;
5264
this.requestIntercept = intercept;
5365
}
5466

5567
@Override
56-
@SuppressWarnings("unchecked")
5768
public <T> T create(Class<T> clientInterface) {
5869
if (!clientInterface.isInterface()) {
5970
throw new IllegalArgumentException("API declarations must be interfaces.");
@@ -109,6 +120,10 @@ public UrlBuilder url() {
109120
return new UrlBuilder(baseUrl);
110121
}
111122

123+
public Function<HttpException, RuntimeException> errorMapper() {
124+
return errorHandler;
125+
}
126+
112127
@Override
113128
public java.net.http.HttpClient httpClient() {
114129
return httpClient;
@@ -184,19 +199,6 @@ public long avgMicros() {
184199
}
185200
}
186201

187-
@Override
188-
public void checkResponse(HttpResponse<?> response) {
189-
if (response.statusCode() >= 300) {
190-
throw new HttpException(response, this);
191-
}
192-
}
193-
194-
void checkMaybeThrow(HttpResponse<byte[]> response) {
195-
if (response.statusCode() >= 300) {
196-
throw new HttpException(this, response);
197-
}
198-
}
199-
200202
@SuppressWarnings("unchecked")
201203
public BodyContent readErrorContent(boolean responseAsBytes, HttpResponse<?> httpResponse) {
202204
if (responseAsBytes) {
@@ -259,16 +261,28 @@ String firstHeader(HttpHeaders headers, String... names) {
259261
<T> HttpResponse<T> send(HttpRequest.Builder requestBuilder, HttpResponse.BodyHandler<T> bodyHandler) {
260262
try {
261263
return httpClient.send(requestBuilder.build(), bodyHandler);
262-
} catch (final IOException e) {
263-
throw new HttpException(499, e);
264264
} catch (final InterruptedException e) {
265265
Thread.currentThread().interrupt();
266266
throw new HttpException(499, e);
267+
} catch (final Exception e) {
268+
throw new HttpException(499, e);
267269
}
268270
}
269271

270-
<T> CompletableFuture<HttpResponse<T>> sendAsync(HttpRequest.Builder requestBuilder, HttpResponse.BodyHandler<T> bodyHandler) {
271-
return httpClient.sendAsync(requestBuilder.build(), bodyHandler);
272+
<T> CompletableFuture<HttpResponse<T>> sendAsync(
273+
HttpRequest.Builder requestBuilder, HttpResponse.BodyHandler<T> bodyHandler) {
274+
return httpClient
275+
.sendAsync(requestBuilder.build(), bodyHandler)
276+
.handle(
277+
(r, e) -> {
278+
if (e != null) {
279+
if (e.getCause() instanceof InterruptedException) {
280+
Thread.currentThread().interrupt();
281+
}
282+
throw new HttpException(499, e.getCause());
283+
}
284+
return r;
285+
});
272286
}
273287

274288
<T> BodyContent write(T bean, Class<?> type, String contentType) {

http-client/src/main/java/io/avaje/http/client/DHttpClientContextBuilder.java

Lines changed: 0 additions & 180 deletions
This file was deleted.

0 commit comments

Comments
 (0)