From b7748b59a99f50bd652b2f3f35f3cafa3690b90c Mon Sep 17 00:00:00 2001 From: box-sdk-build Date: Mon, 16 Feb 2026 02:50:14 -0800 Subject: [PATCH 1/5] test: assume that exception is thrown from delete archive (box/box-codegen#927) --- .codegen.json | 2 +- src/test/java/com/box/sdkgen/archives/ArchivesITest.java | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.codegen.json b/.codegen.json index 11364ffb4..c0669ab2e 100644 --- a/.codegen.json +++ b/.codegen.json @@ -1 +1 @@ -{ "engineHash": "bfb97cc", "specHash": "77eac4b", "version": "10.5.0" } +{ "engineHash": "f36ed52", "specHash": "77eac4b", "version": "10.5.0" } diff --git a/src/test/java/com/box/sdkgen/archives/ArchivesITest.java b/src/test/java/com/box/sdkgen/archives/ArchivesITest.java index d02b09b34..03bc91d7d 100644 --- a/src/test/java/com/box/sdkgen/archives/ArchivesITest.java +++ b/src/test/java/com/box/sdkgen/archives/ArchivesITest.java @@ -52,7 +52,6 @@ public void testArchivesCreateListDelete() { .getArchives() .getArchivesV2025R0(new GetArchivesV2025R0QueryParams.Builder().limit(100L).build()); assert archives.getEntries().size() > 0; - client.getArchives().deleteArchiveByIdV2025R0(archive.getId()); assertThrows( RuntimeException.class, () -> client.getArchives().deleteArchiveByIdV2025R0(archive.getId())); From 7d90a3fb2d137e4435dac00de5ae4df6ff65e065 Mon Sep 17 00:00:00 2001 From: box-sdk-build Date: Mon, 16 Feb 2026 06:20:25 -0800 Subject: [PATCH 2/5] chore: Update `.codegen.json` with commit hash of `codegen` and `openapi` spec [skip ci] --- .codegen.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.codegen.json b/.codegen.json index c0669ab2e..98c72adbd 100644 --- a/.codegen.json +++ b/.codegen.json @@ -1 +1 @@ -{ "engineHash": "f36ed52", "specHash": "77eac4b", "version": "10.5.0" } +{ "engineHash": "9dcb945", "specHash": "77eac4b", "version": "10.5.0" } From 95d0b72fd8b32ba2794c0a9cfb160b8bc10cb661 Mon Sep 17 00:00:00 2001 From: box-sdk-build Date: Mon, 16 Feb 2026 09:20:32 -0800 Subject: [PATCH 3/5] docs: Improve documentation for retry strategies (box/box-codegen#925) --- .codegen.json | 2 +- docs/configuration.md | 146 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 136 insertions(+), 12 deletions(-) diff --git a/.codegen.json b/.codegen.json index 98c72adbd..fcdea3595 100644 --- a/.codegen.json +++ b/.codegen.json @@ -1 +1 @@ -{ "engineHash": "9dcb945", "specHash": "77eac4b", "version": "10.5.0" } +{ "engineHash": "482939a", "specHash": "77eac4b", "version": "10.5.0" } diff --git a/docs/configuration.md b/docs/configuration.md index ab18f97a8..8b49875b1 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -3,38 +3,162 @@ -- [Configuration](#configuration) - - [Max retry attempts](#max-retry-attempts) - - [Custom retry strategy](#custom-retry-strategy) +- [Retry Strategy](#retry-strategy) + - [Overview](#overview) + - [Default Configuration](#default-configuration) + - [Retry Decision Flow](#retry-decision-flow) + - [Exponential Backoff Algorithm](#exponential-backoff-algorithm) + - [Example Delays (with default settings)](#example-delays-with-default-settings) + - [Retry-After Header](#retry-after-header) + - [Network Exception Handling](#network-exception-handling) + - [Customizing Retry Parameters](#customizing-retry-parameters) + - [Custom Retry Strategy](#custom-retry-strategy) -## Max retry attempts +## Retry Strategy -The default maximum number of retries in case of failed API call is 5. -To change this number you should initialize `BoxRetryStrategy` with the new value and pass it to `NetworkSession`. +### Overview + +The SDK ships with a built-in retry strategy (`BoxRetryStrategy`) that implements the `RetryStrategy` interface. The `BoxNetworkClient`, which serves as the default network client, uses this strategy to automatically retry failed API requests with exponential backoff. + +The retry strategy exposes two methods: + +- **`shouldRetry`** — Determines whether a failed request should be retried based on the HTTP status code, response headers, attempt count, and authentication state. +- **`retryAfter`** — Computes the delay (in seconds) before the next retry attempt, using either the server-provided `Retry-After` header or an exponential backoff formula. + +### Default Configuration + +| Parameter | Default | Description | +| -------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `maxAttempts` | `5` | Maximum number of retry attempts for HTTP error responses (status 4xx/5xx). | +| `retryBaseInterval` | `1` (second) | Base interval used in the exponential backoff calculation. | +| `retryRandomizationFactor` | `0.5` | Jitter factor applied to the backoff delay. The actual delay is multiplied by a random value between `1 - factor` and `1 + factor`. | +| `maxRetriesOnException` | `2` | Maximum number of retries for network-level exceptions (connection failures, timeouts). These are tracked by a separate counter from HTTP error retries. | + +### Retry Decision Flow + +The following diagram shows how `BoxRetryStrategy.shouldRetry` decides whether to retry a request: + +``` + shouldRetry(fetchOptions, fetchResponse, attemptNumber) + | + v + +-----------------------+ + | status == 0 | Yes + | (network exception)? |----------> attemptNumber <= maxRetriesOnException? + +-----------------------+ | | + | No Yes No + v | | + +-----------------------+ [RETRY] [NO RETRY] + | attemptNumber >= | + | maxAttempts? | + +-----------------------+ + | | + Yes No + | | + [NO RETRY] v + +-----------------------+ + | status == 202 AND | Yes + | Retry-After header? |----------> [RETRY] + +-----------------------+ + | No + v + +-----------------------+ + | status >= 500 | Yes + | (server error)? |----------> [RETRY] + +-----------------------+ + | No + v + +-----------------------+ + | status == 429 | Yes + | (rate limited)? |----------> [RETRY] + +-----------------------+ + | No + v + +-----------------------+ + | status == 401 AND | Yes + | auth available? |----------> Refresh token, then [RETRY] + +-----------------------+ + | No + v + [NO RETRY] +``` + +### Exponential Backoff Algorithm + +When the response does not include a `Retry-After` header, the retry delay is computed using exponential backoff with randomized jitter: + +``` +delay = 2^attemptNumber * retryBaseInterval * random(1 - factor, 1 + factor) +``` + +Where: + +- `attemptNumber` is the current attempt (1-based) +- `retryBaseInterval` defaults to `1` second +- `factor` is `retryRandomizationFactor` (default `0.5`) +- `random(min, max)` returns a uniformly distributed value in `[min, max]` + +#### Example Delays (with default settings) + +| Attempt | Base Delay | Min Delay (factor=0.5) | Max Delay (factor=0.5) | +| ------- | ---------- | ---------------------- | ---------------------- | +| 1 | 2s | 1.0s | 3.0s | +| 2 | 4s | 2.0s | 6.0s | +| 3 | 8s | 4.0s | 12.0s | +| 4 | 16s | 8.0s | 24.0s | + +### Retry-After Header + +When the server includes a `Retry-After` header in the response, the SDK uses the header value directly as the delay in seconds instead of computing an exponential backoff delay. This applies to any retryable response that includes the header, including: + +- `202 Accepted` with `Retry-After` (long-running operations) +- `429 Too Many Requests` with `Retry-After` +- `5xx` server errors with `Retry-After` + +The header value is parsed as a floating-point number representing seconds. + +### Network Exception Handling + +Network-level failures (connection refused, DNS resolution errors, timeouts, TLS errors) are represented internally as responses with status `0`. These exceptions are tracked by a **separate counter** (`maxRetriesOnException`, default `2`) from the regular HTTP error retry counter (`maxAttempts`). + +This means: + +- Network exception retries are tracked independently from HTTP error retries, each with their own counter and backoff progression. +- A request can fail up to `maxRetriesOnException` times due to network exceptions, but each exception retry also increments the overall attempt counter, so the total number of retries across both exception and HTTP error types is bounded by `maxAttempts`. + +### Customizing Retry Parameters + +You can customize all retry parameters by initializing `BoxRetryStrategy` with the desired values and passing it to `NetworkSession`: ```java BoxDeveloperTokenAuth auth = new BoxDeveloperTokenAuth("DEVELOPER_TOKEN"); NetworkSession session = new NetworkSession.Builder() - .retryStrategy(new BoxRetryStrategy.Builder().maxAttempts(3).build()) + .retryStrategy( + new BoxRetryStrategy.Builder() + .maxAttempts(3) + .retryBaseInterval(2) + .retryRandomizationFactor(0.3) + .maxRetriesOnException(1) + .build() + ) .build(); BoxClient client = new BoxClient.Builder(auth) .networkSession(session) .build(); ``` -## Custom retry strategy +### Custom Retry Strategy -You can also implement your own retry strategy by subclassing `RetryStrategy` and overriding `shouldRetry` and `retryAfter` methods. -This example shows how to set custom strategy that retries on 5xx status codes and waits 1 second between retries. +You can implement your own retry strategy by implementing the `RetryStrategy` interface and overriding the `shouldRetry` and `retryAfter` methods: ```java BoxDeveloperTokenAuth auth = new BoxDeveloperTokenAuth("DEVELOPER_TOKEN"); RetryStrategy customRetryStrategy = new RetryStrategy() { @Override public boolean shouldRetry(FetchOptions fetchOptions, FetchResponse fetchResponse, int attemptNumber) { - return fetchResponse.status >= 500; + return fetchResponse.getStatus() >= 500 && attemptNumber < 3; } @Override From c1e93dab2449423f9f22b8d43e373190b02ca037 Mon Sep 17 00:00:00 2001 From: box-sdk-build Date: Wed, 18 Feb 2026 08:50:19 -0800 Subject: [PATCH 4/5] feat: Add customizable timeouts for SDKs (box/box-codegen#924) --- .codegen.json | 2 +- docs/client.md | 13 ++++++ docs/configuration.md | 32 +++++++++++++ .../java/com/box/sdkgen/client/BoxClient.java | 12 +++++ .../boxnetworkclient/BoxNetworkClient.java | 26 +++++++++++ .../networking/network/NetworkSession.java | 45 +++++++++++++++++++ .../timeoutconfig/TimeoutConfig.java | 44 ++++++++++++++++++ .../com/box/sdkgen/client/ClientITest.java | 17 +++++++ 8 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/box/sdkgen/networking/timeoutconfig/TimeoutConfig.java diff --git a/.codegen.json b/.codegen.json index fcdea3595..ef6446242 100644 --- a/.codegen.json +++ b/.codegen.json @@ -1 +1 @@ -{ "engineHash": "482939a", "specHash": "77eac4b", "version": "10.5.0" } +{ "engineHash": "bc04b80", "specHash": "77eac4b", "version": "10.5.0" } diff --git a/docs/client.md b/docs/client.md index 9a871d55e..7e63120f4 100644 --- a/docs/client.md +++ b/docs/client.md @@ -17,6 +17,7 @@ divided across resource managers. - [Custom headers](#custom-headers) - [Custom Base URLs](#custom-base-urls) - [Interceptors](#interceptors) +- [Use Timeouts for API calls](#use-timeouts-for-api-calls) - [Use Proxy for API calls](#use-proxy-for-api-calls) @@ -178,6 +179,18 @@ List interceptors = new ArrayList<>() { BoxClient clientWithInterceptor = client.withInterceptors(interceptors); ``` +# Use Timeouts for API calls + +In order to configure timeout for API calls, calling the `client.withTimeouts(config)` method creates a new client with timeout settings, leaving the original client unmodified. + +```java +TimeoutConfig timeoutConfig = new TimeoutConfig.Builder() + .connectionTimeoutMs(10000L) + .readTimeoutMs(30000L) + .build(); +BoxClient newClient = client.withTimeouts(timeoutConfig); +``` + # Use Proxy for API calls In order to use a proxy for API calls, calling the `client.withProxy(proxyConfig)` method creates a new client, leaving the original client unmodified, with the username and password being optional. We only support adding proxy for BoxNetworkClient. If you are using your own implementation of NetworkClient, you would need to configure proxy on your own. diff --git a/docs/configuration.md b/docs/configuration.md index 8b49875b1..cb65813c5 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -13,6 +13,7 @@ - [Network Exception Handling](#network-exception-handling) - [Customizing Retry Parameters](#customizing-retry-parameters) - [Custom Retry Strategy](#custom-retry-strategy) +- [Timeouts](#timeouts) @@ -173,3 +174,34 @@ BoxClient client = new BoxClient.Builder(auth) .networkSession(session) .build(); ``` + +## Timeouts + +You can configure network timeouts with `TimeoutConfig` on `NetworkSession`. +Java SDK supports separate values for connection and read timeouts, both in milliseconds. + +```java +BoxDeveloperTokenAuth auth = new BoxDeveloperTokenAuth("DEVELOPER_TOKEN"); +TimeoutConfig timeoutConfig = new TimeoutConfig.Builder() + .connectionTimeoutMs(10000L) + .readTimeoutMs(30000L) + .build(); + +NetworkSession session = new NetworkSession() + .withTimeoutConfig(timeoutConfig); + +BoxClient client = new BoxClient.Builder(auth) + .networkSession(session) + .build(); +``` + +How timeout handling works: + +- `connectionTimeoutMs` controls how long the client waits to establish a connection. +- `readTimeoutMs` controls how long the client waits for data while reading the response. +- Each timeout is optional. If a value is not provided, the client keeps its existing timeout for that setting. +- To disable both timeouts, set `connectionTimeoutMs(0L)` and `readTimeoutMs(0L)`. +- You can also disable only one timeout by setting just one of them to `0L` and leaving the other configured. +- Timeout failures are handled as request exceptions, then retry behavior is controlled by the configured retry strategy +- If retries are exhausted after timeout failures, the SDK throws `BoxSDKError` with the underlying timeout exception as the cause. +- Timeout applies to a single HTTP request attempt to the Box API (not the total time across all retries). diff --git a/src/main/java/com/box/sdkgen/client/BoxClient.java b/src/main/java/com/box/sdkgen/client/BoxClient.java index 4ead1e87f..e11f46248 100644 --- a/src/main/java/com/box/sdkgen/client/BoxClient.java +++ b/src/main/java/com/box/sdkgen/client/BoxClient.java @@ -92,6 +92,7 @@ import com.box.sdkgen.networking.interceptors.Interceptor; import com.box.sdkgen.networking.network.NetworkSession; import com.box.sdkgen.networking.proxyconfig.ProxyConfig; +import com.box.sdkgen.networking.timeoutconfig.TimeoutConfig; import java.util.List; import java.util.Map; @@ -1046,6 +1047,17 @@ public BoxClient withProxy(ProxyConfig config) { .build(); } + /** + * Create a new client with custom timeouts that will be used for every API call + * + * @param config Timeout configuration. + */ + public BoxClient withTimeouts(TimeoutConfig config) { + return new BoxClient.Builder(this.auth) + .networkSession(this.networkSession.withTimeoutConfig(config)) + .build(); + } + /** * Create a new client with a custom set of interceptors that will be used for every API call * diff --git a/src/main/java/com/box/sdkgen/networking/boxnetworkclient/BoxNetworkClient.java b/src/main/java/com/box/sdkgen/networking/boxnetworkclient/BoxNetworkClient.java index 5f8d18851..a63c8b1d2 100644 --- a/src/main/java/com/box/sdkgen/networking/boxnetworkclient/BoxNetworkClient.java +++ b/src/main/java/com/box/sdkgen/networking/boxnetworkclient/BoxNetworkClient.java @@ -19,6 +19,7 @@ import com.box.sdkgen.networking.network.NetworkSession; import com.box.sdkgen.networking.networkclient.NetworkClient; import com.box.sdkgen.networking.proxyconfig.ProxyConfig; +import com.box.sdkgen.networking.timeoutconfig.TimeoutConfig; import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; import java.net.InetSocketAddress; @@ -97,6 +98,31 @@ public BoxNetworkClient withProxy(ProxyConfig config) { return new BoxNetworkClient(clientBuilder.build()); } + public BoxNetworkClient withTimeoutConfig(TimeoutConfig config) { + if (config == null) { + throw new IllegalArgumentException("TimeoutConfig cannot be null"); + } + + OkHttpClient.Builder clientBuilder = httpClient.newBuilder(); + + Long connectionTimeoutMs = config.getConnectionTimeoutMs(); + if (connectionTimeoutMs != null) { + if (connectionTimeoutMs < 0) { + throw new IllegalArgumentException("connectionTimeoutMs cannot be negative"); + } + clientBuilder.connectTimeout(connectionTimeoutMs.longValue(), TimeUnit.MILLISECONDS); + } + + Long readTimeoutMs = config.getReadTimeoutMs(); + if (readTimeoutMs != null) { + if (readTimeoutMs < 0) { + throw new IllegalArgumentException("readTimeoutMs cannot be negative"); + } + clientBuilder.readTimeout(readTimeoutMs.longValue(), TimeUnit.MILLISECONDS); + } + return new BoxNetworkClient(clientBuilder.build()); + } + public FetchResponse fetch(FetchOptions options) { NetworkSession networkSession = options.getNetworkSession() == null ? new NetworkSession() : options.getNetworkSession(); diff --git a/src/main/java/com/box/sdkgen/networking/network/NetworkSession.java b/src/main/java/com/box/sdkgen/networking/network/NetworkSession.java index 3c453ec9d..60a32bff6 100644 --- a/src/main/java/com/box/sdkgen/networking/network/NetworkSession.java +++ b/src/main/java/com/box/sdkgen/networking/network/NetworkSession.java @@ -9,6 +9,7 @@ import com.box.sdkgen.networking.proxyconfig.ProxyConfig; import com.box.sdkgen.networking.retries.BoxRetryStrategy; import com.box.sdkgen.networking.retries.RetryStrategy; +import com.box.sdkgen.networking.timeoutconfig.TimeoutConfig; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -31,6 +32,8 @@ public class NetworkSession { protected ProxyConfig proxyConfig; + protected TimeoutConfig timeoutConfig; + public NetworkSession() { networkClient = new BoxNetworkClient(); retryStrategy = new BoxRetryStrategy(); @@ -45,6 +48,7 @@ protected NetworkSession(Builder builder) { this.retryStrategy = builder.retryStrategy; this.dataSanitizer = builder.dataSanitizer; this.proxyConfig = builder.proxyConfig; + this.timeoutConfig = builder.timeoutConfig; } public NetworkSession withAdditionalHeaders() { @@ -63,6 +67,7 @@ public NetworkSession withAdditionalHeaders(Map additionalHeader .retryStrategy(this.retryStrategy) .dataSanitizer(this.dataSanitizer) .proxyConfig(this.proxyConfig) + .timeoutConfig(this.timeoutConfig) .build(); } @@ -75,6 +80,7 @@ public NetworkSession withCustomBaseUrls(BaseUrls baseUrls) { .retryStrategy(this.retryStrategy) .dataSanitizer(this.dataSanitizer) .proxyConfig(this.proxyConfig) + .timeoutConfig(this.timeoutConfig) .build(); } @@ -90,6 +96,7 @@ public NetworkSession withInterceptors(List interceptors) { .retryStrategy(this.retryStrategy) .dataSanitizer(this.dataSanitizer) .proxyConfig(this.proxyConfig) + .timeoutConfig(this.timeoutConfig) .build(); } @@ -102,6 +109,7 @@ public NetworkSession withNetworkClient(NetworkClient networkClient) { .retryStrategy(this.retryStrategy) .dataSanitizer(this.dataSanitizer) .proxyConfig(this.proxyConfig) + .timeoutConfig(this.timeoutConfig) .build(); } @@ -114,6 +122,7 @@ public NetworkSession withRetryStrategy(RetryStrategy retryStrategy) { .retryStrategy(retryStrategy) .dataSanitizer(this.dataSanitizer) .proxyConfig(this.proxyConfig) + .timeoutConfig(this.timeoutConfig) .build(); } @@ -126,6 +135,7 @@ public NetworkSession withDataSanitizer(DataSanitizer dataSanitizer) { .retryStrategy(this.retryStrategy) .dataSanitizer(dataSanitizer) .proxyConfig(this.proxyConfig) + .timeoutConfig(this.timeoutConfig) .build(); } @@ -145,6 +155,30 @@ public NetworkSession withProxy(ProxyConfig config) { .retryStrategy(this.retryStrategy) .dataSanitizer(this.dataSanitizer) .proxyConfig(config) + .timeoutConfig(this.timeoutConfig) + .build(); + } + + public NetworkSession withTimeoutConfig(TimeoutConfig timeoutConfig) { + if (timeoutConfig == null) { + throw new IllegalArgumentException("TimeoutConfig cannot be null"); + } + + if (!(this.networkClient instanceof BoxNetworkClient)) { + throw new BoxSDKError("Timeouts are only supported for BoxNetworkClient"); + } + + BoxNetworkClient newClient = + ((BoxNetworkClient) this.networkClient).withTimeoutConfig(timeoutConfig); + return new Builder() + .additionalHeaders(this.additionalHeaders) + .baseUrls(this.baseUrls) + .interceptors(this.interceptors) + .networkClient(newClient) + .retryStrategy(this.retryStrategy) + .dataSanitizer(this.dataSanitizer) + .proxyConfig(this.proxyConfig) + .timeoutConfig(timeoutConfig) .build(); } @@ -176,6 +210,10 @@ public ProxyConfig getProxyConfig() { return proxyConfig; } + public TimeoutConfig getTimeoutConfig() { + return timeoutConfig; + } + public static class Builder { protected Map additionalHeaders = new HashMap<>(); @@ -192,6 +230,8 @@ public static class Builder { protected ProxyConfig proxyConfig; + protected TimeoutConfig timeoutConfig; + public Builder() { networkClient = new BoxNetworkClient(); retryStrategy = new BoxRetryStrategy(); @@ -233,6 +273,11 @@ public Builder proxyConfig(ProxyConfig proxyConfig) { return this; } + public Builder timeoutConfig(TimeoutConfig timeoutConfig) { + this.timeoutConfig = timeoutConfig; + return this; + } + public NetworkSession build() { return new NetworkSession(this); } diff --git a/src/main/java/com/box/sdkgen/networking/timeoutconfig/TimeoutConfig.java b/src/main/java/com/box/sdkgen/networking/timeoutconfig/TimeoutConfig.java new file mode 100644 index 000000000..728f5b092 --- /dev/null +++ b/src/main/java/com/box/sdkgen/networking/timeoutconfig/TimeoutConfig.java @@ -0,0 +1,44 @@ +package com.box.sdkgen.networking.timeoutconfig; + +public class TimeoutConfig { + + public Long connectionTimeoutMs; + + public Long readTimeoutMs; + + public TimeoutConfig() {} + + protected TimeoutConfig(Builder builder) { + this.connectionTimeoutMs = builder.connectionTimeoutMs; + this.readTimeoutMs = builder.readTimeoutMs; + } + + public Long getConnectionTimeoutMs() { + return connectionTimeoutMs; + } + + public Long getReadTimeoutMs() { + return readTimeoutMs; + } + + public static class Builder { + + protected Long connectionTimeoutMs; + + protected Long readTimeoutMs; + + public Builder connectionTimeoutMs(Long connectionTimeoutMs) { + this.connectionTimeoutMs = connectionTimeoutMs; + return this; + } + + public Builder readTimeoutMs(Long readTimeoutMs) { + this.readTimeoutMs = readTimeoutMs; + return this; + } + + public TimeoutConfig build() { + return new TimeoutConfig(this); + } + } +} diff --git a/src/test/java/com/box/sdkgen/client/ClientITest.java b/src/test/java/com/box/sdkgen/client/ClientITest.java index dcae23882..68f4a1a41 100644 --- a/src/test/java/com/box/sdkgen/client/ClientITest.java +++ b/src/test/java/com/box/sdkgen/client/ClientITest.java @@ -26,6 +26,7 @@ import com.box.sdkgen.networking.fetchoptions.MultipartItem; import com.box.sdkgen.networking.fetchoptions.ResponseFormat; import com.box.sdkgen.networking.fetchresponse.FetchResponse; +import com.box.sdkgen.networking.timeoutconfig.TimeoutConfig; import com.box.sdkgen.schemas.filefull.FileFull; import com.box.sdkgen.schemas.files.Files; import com.box.sdkgen.schemas.folderfull.FolderFull; @@ -199,6 +200,22 @@ public void testWithCustomBaseUrls() { assertThrows(RuntimeException.class, () -> customBaseClient.getUsers().getUserMe()); } + @Test + public void testWithTimeoutWhenTimeoutOccurs() { + long readTimeoutMs = 1; + BoxClient clientWithTimeout = + client.withTimeouts(new TimeoutConfig.Builder().readTimeoutMs(readTimeoutMs).build()); + assertThrows(RuntimeException.class, () -> clientWithTimeout.getUsers().getUserMe()); + } + + @Test + public void testWithTimeoutWhenTimeoutDoesNotOccur() { + long readTimeoutMs = 10000; + BoxClient clientWithTimeout = + client.withTimeouts(new TimeoutConfig.Builder().readTimeoutMs(readTimeoutMs).build()); + clientWithTimeout.getUsers().getUserMe(); + } + @Test public void testWithInterceptors() { UserFull user = client.getUsers().getUserMe(); From edc25d9cb618cbe761dfc9904dc61ac22ff1abdd Mon Sep 17 00:00:00 2001 From: box-sdk-build Date: Thu, 19 Feb 2026 06:50:18 -0800 Subject: [PATCH 5/5] docs: Update description for delete archives endpoint (box/box-openapi#585) --- .codegen.json | 2 +- docs/archives.md | 4 ++++ .../com/box/sdkgen/managers/archives/ArchivesManager.java | 6 ++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.codegen.json b/.codegen.json index ef6446242..2afbe79cf 100644 --- a/.codegen.json +++ b/.codegen.json @@ -1 +1 @@ -{ "engineHash": "bc04b80", "specHash": "77eac4b", "version": "10.5.0" } +{ "engineHash": "bc04b80", "specHash": "f2523d5", "version": "10.5.0" } diff --git a/docs/archives.md b/docs/archives.md index ad0d5c916..38be510cd 100644 --- a/docs/archives.md +++ b/docs/archives.md @@ -74,6 +74,10 @@ Permanently deletes an archive. To learn more about the archive APIs, see the [Archive API Guide](https://developer.box.com/guides/archives). + +This endpoint is currently unavailable. Please contact support for assistance. + + This operation is performed by calling function `deleteArchiveByIdV2025R0`. See the endpoint docs at diff --git a/src/main/java/com/box/sdkgen/managers/archives/ArchivesManager.java b/src/main/java/com/box/sdkgen/managers/archives/ArchivesManager.java index c49f35b7f..faf6792fb 100644 --- a/src/main/java/com/box/sdkgen/managers/archives/ArchivesManager.java +++ b/src/main/java/com/box/sdkgen/managers/archives/ArchivesManager.java @@ -155,6 +155,9 @@ public ArchiveV2025R0 createArchiveV2025R0( *

To learn more about the archive APIs, see the [Archive API * Guide](https://developer.box.com/guides/archives). * + *

<Danger> This endpoint is currently unavailable. Please contact support for + * assistance. </Danger> + * * @param archiveId The ID of the archive. Example: "982312" */ public void deleteArchiveByIdV2025R0(String archiveId) { @@ -167,6 +170,9 @@ public void deleteArchiveByIdV2025R0(String archiveId) { *

To learn more about the archive APIs, see the [Archive API * Guide](https://developer.box.com/guides/archives). * + *

<Danger> This endpoint is currently unavailable. Please contact support for + * assistance. </Danger> + * * @param archiveId The ID of the archive. Example: "982312" * @param headers Headers of deleteArchiveByIdV2025R0 method */