Skip to content

Commit 26da957

Browse files
committed
fix: async contract leak
1 parent ca3c977 commit 26da957

3 files changed

Lines changed: 18 additions & 31 deletions

File tree

src/main/java/dev/openfga/sdk/api/client/ApiExecutor.java

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,8 @@ public ApiExecutor(ApiClient apiClient, Configuration configuration) {
5151
*
5252
* @param requestBuilder Request configuration
5353
* @return CompletableFuture with API response containing string data
54-
* @throws FgaInvalidParameterException If configuration is invalid
55-
* @throws ApiException If request construction fails
5654
*/
57-
public CompletableFuture<ApiResponse<String>> send(ApiExecutorRequestBuilder requestBuilder)
58-
throws FgaInvalidParameterException, ApiException {
55+
public CompletableFuture<ApiResponse<String>> send(ApiExecutorRequestBuilder requestBuilder) {
5956
return send(requestBuilder, String.class);
6057
}
6158

@@ -66,11 +63,8 @@ public CompletableFuture<ApiResponse<String>> send(ApiExecutorRequestBuilder req
6663
* @param requestBuilder Request configuration
6764
* @param responseType Class to deserialize response into
6865
* @return CompletableFuture with API response containing typed data
69-
* @throws FgaInvalidParameterException If configuration is invalid
70-
* @throws ApiException If request construction fails
7166
*/
72-
public <T> CompletableFuture<ApiResponse<T>> send(ApiExecutorRequestBuilder requestBuilder, Class<T> responseType)
73-
throws FgaInvalidParameterException, ApiException {
67+
public <T> CompletableFuture<ApiResponse<T>> send(ApiExecutorRequestBuilder requestBuilder, Class<T> responseType) {
7468
if (requestBuilder == null) {
7569
throw new IllegalArgumentException("Request builder cannot be null");
7670
}
@@ -87,7 +81,7 @@ public <T> CompletableFuture<ApiResponse<T>> send(ApiExecutorRequestBuilder requ
8781
return new HttpRequestAttempt<>(httpRequest, methodName, responseType, apiClient, configuration)
8882
.attemptHttpRequest();
8983

90-
} catch (IOException e) {
84+
} catch (FgaInvalidParameterException | IOException | IllegalArgumentException | ApiException e) {
9185
return CompletableFuture.failedFuture(new ApiException(e));
9286
}
9387
}

src/main/java/dev/openfga/sdk/api/client/StreamingApiExecutor.java

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,8 @@ private static <V> V requireNonNull(V value, String message) {
9191
* structures or call {@link java.util.concurrent.CompletableFuture#get()
9292
* get()} before accessing results from the calling thread.
9393
* @return CompletableFuture&lt;Void&gt; that completes when the stream is exhausted,
94-
* or fails exceptionally. All errors — including null arguments, configuration
95-
* validation failures, and HTTP errors — are routed through the future;
96-
* callers only need {@code .exceptionally()} handling.
94+
* or fails exceptionally for configuration or HTTP errors.
95+
* @throws IllegalArgumentException if {@code requestBuilder} or {@code consumer} is null
9796
*/
9897
public CompletableFuture<Void> stream(ApiExecutorRequestBuilder requestBuilder, Consumer<T> consumer) {
9998
return stream(requestBuilder, consumer, null);
@@ -110,21 +109,21 @@ public CompletableFuture<Void> stream(ApiExecutorRequestBuilder requestBuilder,
110109
* {@code CompletableFuture} always reflects the error regardless of
111110
* whether an {@code errorConsumer} is present.
112111
* @return CompletableFuture&lt;Void&gt; that completes when the stream is exhausted,
113-
* or fails exceptionally. All errors — including null arguments, configuration
114-
* validation failures, and HTTP errors — are routed through the future;
115-
* callers only need {@code .exceptionally()} handling.
112+
* or fails exceptionally for configuration or HTTP errors.
113+
* @throws IllegalArgumentException if {@code requestBuilder} or {@code consumer} is null
116114
*/
117115
public CompletableFuture<Void> stream(
118116
ApiExecutorRequestBuilder requestBuilder,
119117
Consumer<T> consumer,
120118
@Nullable Consumer<Throwable> errorConsumer) {
119+
if (requestBuilder == null) {
120+
throw new IllegalArgumentException("Request builder cannot be null");
121+
}
122+
if (consumer == null) {
123+
throw new IllegalArgumentException("Consumer cannot be null");
124+
}
125+
121126
try {
122-
if (requestBuilder == null) {
123-
throw new IllegalArgumentException("Request builder cannot be null");
124-
}
125-
if (consumer == null) {
126-
throw new IllegalArgumentException("Consumer cannot be null");
127-
}
128127
configuration.assertValid();
129128
return processStreamingResponse(
130129
requestBuilder.buildHttpRequest(configuration, apiClient), consumer, errorConsumer);

src/test/java/dev/openfga/sdk/api/client/StreamingApiExecutorTest.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -323,24 +323,18 @@ public void streamingApiExecutor_typeReferenceOverload_works() throws Exception
323323
}
324324

325325
@Test
326-
public void stream_throwsForNullRequestBuilder() throws Exception {
326+
public void stream_throwsForNullRequestBuilder() {
327327
StreamingApiExecutor<StreamedListObjectsResponse> executor =
328328
fga.streamingApiExecutor(StreamedListObjectsResponse.class);
329-
CompletableFuture<Void> future = executor.stream(null, obj -> {});
330-
ExecutionException ex = assertThrows(ExecutionException.class, future::get);
331-
assertInstanceOf(ApiException.class, ex.getCause());
332-
assertInstanceOf(IllegalArgumentException.class, ex.getCause().getCause());
329+
assertThrows(IllegalArgumentException.class, () -> executor.stream(null, obj -> {}));
333330
}
334331

335332
@Test
336-
public void stream_throwsForNullConsumer() throws Exception {
333+
public void stream_throwsForNullConsumer() {
337334
StreamingApiExecutor<StreamedListObjectsResponse> executor =
338335
fga.streamingApiExecutor(StreamedListObjectsResponse.class);
339336
ApiExecutorRequestBuilder request = buildStreamedListObjectsRequest();
340-
CompletableFuture<Void> future = executor.stream(request, null);
341-
ExecutionException ex = assertThrows(ExecutionException.class, future::get);
342-
assertInstanceOf(ApiException.class, ex.getCause());
343-
assertInstanceOf(IllegalArgumentException.class, ex.getCause().getCause());
337+
assertThrows(IllegalArgumentException.class, () -> executor.stream(request, null));
344338
}
345339

346340
@Test

0 commit comments

Comments
 (0)