Skip to content

Conversation

@fern-api
Copy link
Contributor

@fern-api fern-api bot commented Dec 4, 2025

This PR regenerates code to match the latest API Definition.

@jverce jverce force-pushed the fern-bot/2025-12-04T19-11Z branch 2 times, most recently from 8099c0e to bace474 Compare December 4, 2025 21:39
@jverce jverce force-pushed the fern-bot/2025-12-04T19-11Z branch from bace474 to d8a9748 Compare December 4, 2025 21:40
@jverce jverce requested a review from Copilot December 4, 2025 22:13
Copilot finished reviewing on behalf of jverce December 4, 2025 22:17
Copy link

Copilot AI left a 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 ProxyResponse class as a union type to differentiate between JSON and stream responses based on Content-Type
  • Updates all proxy client methods to return ProxyResponse instead of generic Object
  • 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 Response object 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 Response object 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 Response object 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 Response object 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 Response object 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 Response object 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 Response object 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 Response object 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 Response object 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 Response object 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants