-
Notifications
You must be signed in to change notification settings - Fork 2
🌿 Fern Regeneration -- December 4, 2025 #195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
8099c0e to
bace474
Compare
bace474 to
d8a9748
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR regenerates code from the Fern API definition, introducing a new ProxyResponse union type to handle both JSON and binary stream responses from the proxy API. The version is bumped from 1.1.0 to 1.1.1.
- Introduces
ProxyResponseclass as a union type to differentiate between JSON and stream responses based on Content-Type - Updates all proxy client methods to return
ProxyResponseinstead of genericObject - Adds comprehensive wire tests covering JSON responses, binary streams, and redirect handling
Reviewed changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| ProxyResponse.java | New union type class implementing Closeable, handling both JSON and stream responses with proper resource management |
| RawProxyClient.java | Updated return types and added parseSuccessResponse() helper; removed try-with-resources leading to resource leaks |
| AsyncRawProxyClient.java | Updated async return types and added handleSuccessResponse() helper; removed try-with-resources leading to resource leaks |
| ProxyClient.java | Updated return types from Object to ProxyResponse for all HTTP methods |
| AsyncProxyClient.java | Updated async return types from Object to ProxyResponse for all HTTP methods |
| ProxyClientWireTest.java | Comprehensive new test suite covering JSON, binary stream, and redirect scenarios for both sync and async clients |
| ClientOptions.java | Version string updated from 1.1.0 to 1.1.1 |
| build.gradle | Version updated from 1.1.0 to 1.1.1 |
| README.md | Added table of contents and updated version from 1.1.0 to 1.1.1 |
Critical Issues Found: The removal of try-with-resources for Response objects in both sync and async clients creates resource leaks in all error paths. The Response must be explicitly closed when errors occur, otherwise HTTP connections will leak. This affects all HTTP methods (GET, POST, PUT, DELETE, PATCH) in both RawProxyClient and AsyncRawProxyClient.
Comments suppressed due to low confidence (10)
src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java:119
- Critical resource leak: The
Responseobject is not closed in error paths. When an error occurs (lines 102-115), the response remains open, potentially leaking connections. The previous code used try-with-resources to automatically close the response. Now that this is removed, you must explicitly close the response in all error paths, or wrap the entire try block with proper resource management.
Recommendation: Add response.close() in the error paths before throwing exceptions, or revert to using try-with-resources for the Response object.
try {
Response response = client.newCall(okhttpRequest).execute();
ResponseBody responseBody = response.body();
if (response.isSuccessful()) {
return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response);
}
String responseBodyString = responseBody != null ? responseBody.string() : "{}";
try {
if (response.code() == 429) {
throw new TooManyRequestsError(
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response);
}
} catch (JsonProcessingException ignored) {
// unable to map error response, throwing generic error
}
throw new BaseClientApiException(
"Error with status code " + response.code(),
response.code(),
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
response);
} catch (IOException e) {
throw new BaseClientException("Network error executing HTTP request", e);
}
}
src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java:143
- Critical resource leak: The
Responseobject is not closed in error paths. When errors occur (lines 124-142), the response remains open, potentially leaking connections. The previous code used try-with-resources to automatically close the response.
Recommendation: Add response.close() calls in all error completion paths before calling future.completeExceptionally(), or ensure the response is always closed via finally block.
try {
ResponseBody responseBody = response.body();
if (response.isSuccessful()) {
handleSuccessResponse(response, responseBody, future);
return;
}
String responseBodyString = responseBody != null ? responseBody.string() : "{}";
try {
if (response.code() == 429) {
future.completeExceptionally(new TooManyRequestsError(
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response));
return;
}
} catch (JsonProcessingException ignored) {
// unable to map error response, throwing generic error
}
future.completeExceptionally(new BaseClientApiException(
"Error with status code " + response.code(),
response.code(),
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
response));
return;
} catch (IOException e) {
future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e));
}
}
src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java:366
- Critical resource leak: The
Responseobject is not closed in error paths (same issue as in other async methods). When errors occur, the response remains open, potentially leaking connections.
Recommendation: Add response.close() calls in all error completion paths before calling future.completeExceptionally(), or ensure the response is always closed via finally block.
try {
ResponseBody responseBody = response.body();
if (response.isSuccessful()) {
handleSuccessResponse(response, responseBody, future);
return;
}
String responseBodyString = responseBody != null ? responseBody.string() : "{}";
try {
if (response.code() == 429) {
future.completeExceptionally(new TooManyRequestsError(
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response));
return;
}
} catch (JsonProcessingException ignored) {
// unable to map error response, throwing generic error
}
future.completeExceptionally(new BaseClientApiException(
"Error with status code " + response.code(),
response.code(),
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
response));
return;
} catch (IOException e) {
future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e));
}
}
src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java:182
- Critical resource leak: The
Responseobject is not closed in error paths (same issue as in the GET method). When an error occurs (lines 165-178), the response remains open, potentially leaking connections.
Recommendation: Add response.close() in the error paths before throwing exceptions, or revert to using try-with-resources for the Response object.
try {
Response response = client.newCall(okhttpRequest).execute();
ResponseBody responseBody = response.body();
if (response.isSuccessful()) {
return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response);
}
String responseBodyString = responseBody != null ? responseBody.string() : "{}";
try {
if (response.code() == 429) {
throw new TooManyRequestsError(
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response);
}
} catch (JsonProcessingException ignored) {
// unable to map error response, throwing generic error
}
throw new BaseClientApiException(
"Error with status code " + response.code(),
response.code(),
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
response);
} catch (IOException e) {
throw new BaseClientException("Network error executing HTTP request", e);
}
}
src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java:245
- Critical resource leak: The
Responseobject is not closed in error paths (same issue as in the GET and POST methods). When an error occurs, the response remains open, potentially leaking connections.
Recommendation: Add response.close() in the error paths before throwing exceptions, or revert to using try-with-resources for the Response object.
try {
Response response = client.newCall(okhttpRequest).execute();
ResponseBody responseBody = response.body();
if (response.isSuccessful()) {
return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response);
}
String responseBodyString = responseBody != null ? responseBody.string() : "{}";
try {
if (response.code() == 429) {
throw new TooManyRequestsError(
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response);
}
} catch (JsonProcessingException ignored) {
// unable to map error response, throwing generic error
}
throw new BaseClientApiException(
"Error with status code " + response.code(),
response.code(),
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
response);
} catch (IOException e) {
throw new BaseClientException("Network error executing HTTP request", e);
}
}
src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java:363
- Critical resource leak: The
Responseobject is not closed in error paths (same issue as in other HTTP methods). When an error occurs, the response remains open, potentially leaking connections.
Recommendation: Add response.close() in the error paths before throwing exceptions, or revert to using try-with-resources for the Response object.
try {
Response response = client.newCall(okhttpRequest).execute();
ResponseBody responseBody = response.body();
if (response.isSuccessful()) {
return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response);
}
String responseBodyString = responseBody != null ? responseBody.string() : "{}";
try {
if (response.code() == 429) {
throw new TooManyRequestsError(
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response);
}
} catch (JsonProcessingException ignored) {
// unable to map error response, throwing generic error
}
throw new BaseClientApiException(
"Error with status code " + response.code(),
response.code(),
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
response);
} catch (IOException e) {
throw new BaseClientException("Network error executing HTTP request", e);
}
}
src/main/java/com/pipedream/api/resources/proxy/RawProxyClient.java:300
- Critical resource leak: The
Responseobject is not closed in error paths (same issue as in other HTTP methods). When an error occurs, the response remains open, potentially leaking connections.
Recommendation: Add response.close() in the error paths before throwing exceptions, or revert to using try-with-resources for the Response object.
try {
Response response = client.newCall(okhttpRequest).execute();
ResponseBody responseBody = response.body();
if (response.isSuccessful()) {
return new BaseClientHttpResponse<>(parseSuccessResponse(response, responseBody), response);
}
String responseBodyString = responseBody != null ? responseBody.string() : "{}";
try {
if (response.code() == 429) {
throw new TooManyRequestsError(
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response);
}
} catch (JsonProcessingException ignored) {
// unable to map error response, throwing generic error
}
throw new BaseClientApiException(
"Error with status code " + response.code(),
response.code(),
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
response);
} catch (IOException e) {
throw new BaseClientException("Network error executing HTTP request", e);
}
}
src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java:220
- Critical resource leak: The
Responseobject is not closed in error paths (same issue as in the GET method). When errors occur, the response remains open, potentially leaking connections.
Recommendation: Add response.close() calls in all error completion paths before calling future.completeExceptionally(), or ensure the response is always closed via finally block.
try {
ResponseBody responseBody = response.body();
if (response.isSuccessful()) {
handleSuccessResponse(response, responseBody, future);
return;
}
String responseBodyString = responseBody != null ? responseBody.string() : "{}";
try {
if (response.code() == 429) {
future.completeExceptionally(new TooManyRequestsError(
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response));
return;
}
} catch (JsonProcessingException ignored) {
// unable to map error response, throwing generic error
}
future.completeExceptionally(new BaseClientApiException(
"Error with status code " + response.code(),
response.code(),
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
response));
return;
} catch (IOException e) {
future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e));
}
}
src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java:297
- Critical resource leak: The
Responseobject is not closed in error paths (same issue as in other async methods). When errors occur, the response remains open, potentially leaking connections.
Recommendation: Add response.close() calls in all error completion paths before calling future.completeExceptionally(), or ensure the response is always closed via finally block.
try {
ResponseBody responseBody = response.body();
if (response.isSuccessful()) {
handleSuccessResponse(response, responseBody, future);
return;
}
String responseBodyString = responseBody != null ? responseBody.string() : "{}";
try {
if (response.code() == 429) {
future.completeExceptionally(new TooManyRequestsError(
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response));
return;
}
} catch (JsonProcessingException ignored) {
// unable to map error response, throwing generic error
}
future.completeExceptionally(new BaseClientApiException(
"Error with status code " + response.code(),
response.code(),
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
response));
return;
} catch (IOException e) {
future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e));
}
}
src/main/java/com/pipedream/api/resources/proxy/AsyncRawProxyClient.java:443
- Critical resource leak: The
Responseobject is not closed in error paths (same issue as in other async methods). When errors occur, the response remains open, potentially leaking connections.
Recommendation: Add response.close() calls in all error completion paths before calling future.completeExceptionally(), or ensure the response is always closed via finally block.
try {
ResponseBody responseBody = response.body();
if (response.isSuccessful()) {
handleSuccessResponse(response, responseBody, future);
return;
}
String responseBodyString = responseBody != null ? responseBody.string() : "{}";
try {
if (response.code() == 429) {
future.completeExceptionally(new TooManyRequestsError(
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class), response));
return;
}
} catch (JsonProcessingException ignored) {
// unable to map error response, throwing generic error
}
future.completeExceptionally(new BaseClientApiException(
"Error with status code " + response.code(),
response.code(),
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
response));
return;
} catch (IOException e) {
future.completeExceptionally(new BaseClientException("Network error executing HTTP request", e));
}
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This PR regenerates code to match the latest API Definition.