Skip to content

Commit 5d1ee90

Browse files
committed
fix: return API error codes as strings
1 parent 5f8713c commit 5d1ee90

6 files changed

Lines changed: 30 additions & 30 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### Added
1111

1212
- Add `ApiErrorCodes`, grouped constants for documented API root codes and Facturapi-owned validation detail codes.
13-
- Add `FacturapiException.getApiErrorCode()` for the string V2 root error code while preserving `getErrorCode()` compatibility.
13+
- Fix `FacturapiException.getErrorCode()` to return only documented string API root codes.
1414

1515
## [1.3.0] - 2026-06-07
1616

README.es.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ try {
9191
} catch (FacturapiException e) {
9292
System.out.println(e.getMessage());
9393
System.out.println(e.getStatusCode());
94-
if (ApiErrorCodes.RequestErrorCode.RATE_LIMIT_EXCEEDED.equals(e.getApiErrorCode())) {
94+
if (ApiErrorCodes.RequestErrorCode.RATE_LIMIT_EXCEEDED.equals(e.getErrorCode())) {
9595
System.out.println(e.getHeaders().get("retry-after"));
9696
}
9797
System.out.println(e.getErrorPath());

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ try {
9191
} catch (FacturapiException e) {
9292
System.out.println(e.getMessage());
9393
System.out.println(e.getStatusCode());
94-
if (ApiErrorCodes.RequestErrorCode.RATE_LIMIT_EXCEEDED.equals(e.getApiErrorCode())) {
94+
if (ApiErrorCodes.RequestErrorCode.RATE_LIMIT_EXCEEDED.equals(e.getErrorCode())) {
9595
System.out.println(e.getHeaders().get("retry-after"));
9696
}
9797
System.out.println(e.getErrorPath());

src/main/java/io/facturapi/FacturapiException.java

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
public class FacturapiException extends RuntimeException {
99
private final int statusCode;
10-
private final Object errorCode;
10+
private final String errorCode;
1111
private final String errorPath;
1212
private final String errorLocation;
1313
private final JsonNode errors;
@@ -29,14 +29,14 @@ public FacturapiException(String message, Throwable cause) {
2929
this.headers = Collections.emptyMap();
3030
}
3131

32-
public FacturapiException(String message, int statusCode, Object errorCode, String errorPath) {
32+
public FacturapiException(String message, int statusCode, String errorCode, String errorPath) {
3333
this(message, statusCode, errorCode, errorPath, null, null, null, Collections.emptyMap());
3434
}
3535

3636
public FacturapiException(
3737
String message,
3838
int statusCode,
39-
Object errorCode,
39+
String errorCode,
4040
String errorPath,
4141
String errorLocation,
4242
JsonNode errors,
@@ -57,19 +57,10 @@ public int getStatusCode() {
5757
return statusCode;
5858
}
5959

60-
public Object getErrorCode() {
60+
public String getErrorCode() {
6161
return errorCode;
6262
}
6363

64-
/**
65-
* Returns the documented V2 API root error code when the response contains one.
66-
*
67-
* <p>{@link #getErrorCode()} remains available for compatibility with older API responses.</p>
68-
*/
69-
public String getApiErrorCode() {
70-
return errorCode instanceof String ? (String) errorCode : null;
71-
}
72-
7364
public String getErrorPath() {
7465
return errorPath;
7566
}

src/main/java/io/facturapi/http/FacturapiHttpClient.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ private static JsonNode firstDefined(JsonNode node, String... keys) {
210210
private FacturapiException buildApiException(String bodyText, Response response) {
211211
int statusCode = response.code();
212212
int resolvedStatus = statusCode;
213-
Object errorCode = null;
213+
String errorCode = null;
214214
String errorPath = null;
215215
String errorLocation = null;
216216
JsonNode errors = null;
@@ -245,18 +245,8 @@ private FacturapiException buildApiException(String bodyText, Response response)
245245
}
246246

247247
JsonNode codeNode = firstDefined(root, "code");
248-
if (codeNode != null && !codeNode.isNull()) {
249-
if (codeNode.isTextual()) {
250-
errorCode = codeNode.asText();
251-
} else if (codeNode.isIntegralNumber()) {
252-
errorCode = codeNode.intValue();
253-
} else if (codeNode.isNumber()) {
254-
errorCode = codeNode.numberValue();
255-
} else if (codeNode.isBoolean()) {
256-
errorCode = codeNode.asBoolean();
257-
} else {
258-
errorCode = codeNode.toString();
259-
}
248+
if (codeNode != null && codeNode.isTextual()) {
249+
errorCode = codeNode.asText();
260250
}
261251

262252
JsonNode pathNode = firstDefined(root, "path");

src/test/java/io/facturapi/FacturapiHttpClientTest.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
44
import static org.junit.jupiter.api.Assertions.assertEquals;
5+
import static org.junit.jupiter.api.Assertions.assertNull;
56
import static org.junit.jupiter.api.Assertions.assertThrows;
67
import static org.junit.jupiter.api.Assertions.assertTrue;
78

@@ -71,12 +72,30 @@ void throwsFacturapiExceptionWithApiMessage() {
7172
assertEquals(400, ex.getStatusCode());
7273
assertTrue(ex.getMessage().contains("Invalid customer"));
7374
assertEquals(ApiErrorCodes.RequestErrorCode.INVALID_REQUEST, ex.getErrorCode());
74-
assertEquals(ApiErrorCodes.RequestErrorCode.INVALID_REQUEST, ex.getApiErrorCode());
7575
assertEquals("customer.tax_id", ex.getErrorPath());
7676
assertEquals("body", ex.getErrorLocation());
7777
assertEquals("log_123", ex.getLogId());
7878
assertEquals("required", ex.getErrors().get(0).get("code").asText());
7979
assertEquals("3", ex.getHeaders().get("Retry-After").get(0));
8080
assertEquals("log_123", ex.getHeaders().get("x-facturapi-log-id").get(0));
8181
}
82+
83+
@Test
84+
void ignoresNonStringApiErrorCodes() {
85+
StubHttpClient httpClient = new StubHttpClient();
86+
httpClient.enqueueJson(400, "{\"message\":\"Invalid customer\",\"code\":400}");
87+
88+
FacturapiHttpClient client = new FacturapiHttpClient(
89+
FacturapiConfig.builder("sk_test_123")
90+
.httpClient(httpClient.client())
91+
.build()
92+
);
93+
94+
FacturapiException ex = assertThrows(
95+
FacturapiException.class,
96+
() -> client.get("/customers/cus_1", null, GenericResponse.class)
97+
);
98+
99+
assertNull(ex.getErrorCode());
100+
}
82101
}

0 commit comments

Comments
 (0)