Skip to content

Commit 44cf28f

Browse files
feat: add HTTP 429 and 503 error handling to FHIR client (#101)
Enhance the FHIR client with comprehensive error handling for rate limiting (429) and service unavailability (503) scenarios. This improves the SDK's resilience and provides better error feedback to developers. Key changes: - Add TooManyRequestsError for HTTP 429 responses with structured error handling - Add ServiceUnavailableError for HTTP 503 responses with generic error handling - Update both synchronous and asynchronous FHIR clients with new error cases - Import new error classes in client implementations 🌿 Generated with Fern Co-authored-by: fern-api[bot] <115122769+fern-api[bot]@users.noreply.github.com>
1 parent 3922ab5 commit 44cf28f

File tree

7 files changed

+179
-4
lines changed

7 files changed

+179
-4
lines changed

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ java {
4747

4848
group = 'com.phenoml.maven'
4949

50-
version = '9.0.1'
50+
version = '9.1.0'
5151

5252
jar {
5353
dependsOn(":generatePomFileForMavenPublication")
@@ -78,7 +78,7 @@ publishing {
7878
maven(MavenPublication) {
7979
groupId = 'com.phenoml.maven'
8080
artifactId = 'phenoml-java-sdk'
81-
version = '9.0.1'
81+
version = '9.1.0'
8282
from components.java
8383
pom {
8484
name = 'phenoml'

changelog.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## 9.1.0 - 2026-03-09
2+
* feat: add HTTP 429 and 503 error handling to FHIR client
3+
* Enhance the FHIR client with comprehensive error handling for rate limiting (429) and service unavailability (503) scenarios. This improves the SDK's resilience and provides better error feedback to developers.
4+
* Key changes:
5+
* Add TooManyRequestsError for HTTP 429 responses with structured error handling
6+
* Add ServiceUnavailableError for HTTP 503 responses with generic error handling
7+
* Update both synchronous and asynchronous FHIR clients with new error cases
8+
* Import new error classes in client implementations
9+
* 🌿 Generated with Fern
10+
111
## 9.0.0 - 2026-03-04
212

313
### Breaking Changes

src/main/java/com/phenoml/api/core/ClientOptions.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,10 @@ private ClientOptions(
3232
this.headers.putAll(headers);
3333
this.headers.putAll(new HashMap<String, String>() {
3434
{
35-
put("User-Agent", "com.phenoml.maven:phenoml-java-sdk/9.0.1");
35+
put("User-Agent", "com.phenoml.maven:phenoml-java-sdk/9.1.0");
3636
put("X-Fern-Language", "JAVA");
3737
put("X-Fern-SDK-Name", "com.phenoml.fern:api-sdk");
38-
put("X-Fern-SDK-Version", "9.0.1");
38+
put("X-Fern-SDK-Version", "9.1.0");
3939
}
4040
});
4141
this.headerSuppliers = headerSuppliers;

src/main/java/com/phenoml/api/resources/fhir/AsyncRawFhirClient.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
import com.phenoml.api.resources.fhir.errors.BadRequestError;
1717
import com.phenoml.api.resources.fhir.errors.InternalServerError;
1818
import com.phenoml.api.resources.fhir.errors.NotFoundError;
19+
import com.phenoml.api.resources.fhir.errors.ServiceUnavailableError;
20+
import com.phenoml.api.resources.fhir.errors.TooManyRequestsError;
1921
import com.phenoml.api.resources.fhir.errors.UnauthorizedError;
2022
import com.phenoml.api.resources.fhir.requests.FhirCreateRequest;
2123
import com.phenoml.api.resources.fhir.requests.FhirDeleteRequest;
@@ -130,6 +132,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
130132
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
131133
response));
132134
return;
135+
case 429:
136+
future.completeExceptionally(new TooManyRequestsError(
137+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ErrorResponse.class),
138+
response));
139+
return;
133140
case 500:
134141
future.completeExceptionally(new InternalServerError(
135142
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
@@ -140,6 +147,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
140147
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ErrorResponse.class),
141148
response));
142149
return;
150+
case 503:
151+
future.completeExceptionally(new ServiceUnavailableError(
152+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
153+
response));
154+
return;
143155
}
144156
} catch (JsonProcessingException ignored) {
145157
// unable to map error response, throwing generic error
@@ -236,6 +248,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
236248
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
237249
response));
238250
return;
251+
case 429:
252+
future.completeExceptionally(new TooManyRequestsError(
253+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ErrorResponse.class),
254+
response));
255+
return;
239256
case 500:
240257
future.completeExceptionally(new InternalServerError(
241258
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
@@ -246,6 +263,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
246263
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ErrorResponse.class),
247264
response));
248265
return;
266+
case 503:
267+
future.completeExceptionally(new ServiceUnavailableError(
268+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
269+
response));
270+
return;
249271
}
250272
} catch (JsonProcessingException ignored) {
251273
// unable to map error response, throwing generic error
@@ -342,6 +364,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
342364
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
343365
response));
344366
return;
367+
case 429:
368+
future.completeExceptionally(new TooManyRequestsError(
369+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ErrorResponse.class),
370+
response));
371+
return;
345372
case 500:
346373
future.completeExceptionally(new InternalServerError(
347374
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
@@ -352,6 +379,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
352379
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ErrorResponse.class),
353380
response));
354381
return;
382+
case 503:
383+
future.completeExceptionally(new ServiceUnavailableError(
384+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
385+
response));
386+
return;
355387
}
356388
} catch (JsonProcessingException ignored) {
357389
// unable to map error response, throwing generic error
@@ -454,6 +486,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
454486
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
455487
response));
456488
return;
489+
case 429:
490+
future.completeExceptionally(new TooManyRequestsError(
491+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ErrorResponse.class),
492+
response));
493+
return;
457494
case 500:
458495
future.completeExceptionally(new InternalServerError(
459496
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
@@ -464,6 +501,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
464501
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ErrorResponse.class),
465502
response));
466503
return;
504+
case 503:
505+
future.completeExceptionally(new ServiceUnavailableError(
506+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
507+
response));
508+
return;
467509
}
468510
} catch (JsonProcessingException ignored) {
469511
// unable to map error response, throwing generic error
@@ -577,6 +619,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
577619
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
578620
response));
579621
return;
622+
case 429:
623+
future.completeExceptionally(new TooManyRequestsError(
624+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ErrorResponse.class),
625+
response));
626+
return;
580627
case 500:
581628
future.completeExceptionally(new InternalServerError(
582629
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
@@ -587,6 +634,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
587634
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ErrorResponse.class),
588635
response));
589636
return;
637+
case 503:
638+
future.completeExceptionally(new ServiceUnavailableError(
639+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
640+
response));
641+
return;
590642
}
591643
} catch (JsonProcessingException ignored) {
592644
// unable to map error response, throwing generic error
@@ -684,6 +736,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
684736
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
685737
response));
686738
return;
739+
case 429:
740+
future.completeExceptionally(new TooManyRequestsError(
741+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ErrorResponse.class),
742+
response));
743+
return;
687744
case 500:
688745
future.completeExceptionally(new InternalServerError(
689746
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
@@ -694,6 +751,11 @@ public void onResponse(@NotNull Call call, @NotNull Response response) throws IO
694751
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, ErrorResponse.class),
695752
response));
696753
return;
754+
case 503:
755+
future.completeExceptionally(new ServiceUnavailableError(
756+
ObjectMappers.JSON_MAPPER.readValue(responseBodyString, Object.class),
757+
response));
758+
return;
697759
}
698760
} catch (JsonProcessingException ignored) {
699761
// unable to map error response, throwing generic error

0 commit comments

Comments
 (0)