Skip to content

Commit 4bf966f

Browse files
committed
[Java][jersey3] Add error entity deserialization to ApiException
- Add errorEntity field and getErrorEntity() method to ApiException - Add deserializeErrorEntity method to ApiClient - Pass errorTypes map from API methods to invokeAPI - Enables automatic deserialization of error response bodies - Fixes #4777
1 parent 01ef44a commit 4bf966f

File tree

3 files changed

+49
-5
lines changed

3 files changed

+49
-5
lines changed

modules/openapi-generator/src/main/resources/Java/libraries/jersey3/ApiClient.mustache

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import java.util.List;
5454
import java.util.Arrays;
5555
import java.util.ArrayList;
5656
import java.util.Date;
57+
import java.util.Locale;
5758
import java.util.stream.Collectors;
5859
import java.util.stream.Stream;
5960
{{#jsr310}}
@@ -1196,6 +1197,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
11961197
* @param authNames The authentications to apply
11971198
* @param returnType The return type into which to deserialize the response
11981199
* @param isBodyNullable True if the body is nullable
1200+
* @param errorTypes Mapping of error codes to types into which to deserialize the response
11991201
* @return The response body in type of string
12001202
* @throws ApiException API exception
12011203
*/
@@ -1212,7 +1214,9 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
12121214
String contentType,
12131215
String[] authNames,
12141216
GenericType<T> returnType,
1215-
boolean isBodyNullable)
1217+
boolean isBodyNullable,
1218+
Map<String, GenericType> errorTypes
1219+
)
12161220
throws ApiException {
12171221
12181222
String targetURL;
@@ -1223,7 +1227,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
12231227
if (index < 0 || index >= serverConfigurations.size()) {
12241228
throw new ArrayIndexOutOfBoundsException(
12251229
String.format(
1226-
java.util.Locale.ROOT,
1230+
Locale.ROOT,
12271231
"Invalid index %d when selecting the host settings. Must be less than %d",
12281232
index, serverConfigurations.size()));
12291233
}
@@ -1333,14 +1337,16 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
13331337
String respBody = null;
13341338
if (response.hasEntity()) {
13351339
try {
1340+
// call bufferEntity, so that a subsequent call to `readEntity` in `deserialize` doesn't fail
1341+
response.bufferEntity();
13361342
respBody = String.valueOf(response.readEntity(String.class));
13371343
message = respBody;
13381344
} catch (RuntimeException e) {
13391345
// e.printStackTrace();
13401346
}
13411347
}
13421348
throw new ApiException(
1343-
response.getStatus(), message, buildResponseHeaders(response), respBody);
1349+
response.getStatus(), message, buildResponseHeaders(response), respBody, deserializeErrorEntity(errorTypes, response));
13441350
}
13451351
} finally {
13461352
try {
@@ -1351,6 +1357,21 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
13511357
}
13521358
}
13531359
}
1360+
1361+
private Object deserializeErrorEntity(Map<String, GenericType> errorTypes, Response response) {
1362+
if (errorTypes == null) {
1363+
return null;
1364+
}
1365+
GenericType errorType = errorTypes.get(String.valueOf(response.getStatus()));
1366+
if (errorType == null) {
1367+
errorType = errorTypes.get("0"); // "0" is the "default" response
1368+
}
1369+
try {
1370+
return deserialize(response, errorType);
1371+
} catch (Exception e) {
1372+
return String.format("Failed deserializing error entity: %s", e.toString());
1373+
}
1374+
}
13541375
13551376
protected Response sendRequest(String method, Invocation.Builder invocationBuilder, Entity<?> entity) {
13561377
Response response;
@@ -1377,7 +1398,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
13771398
*/
13781399
@Deprecated
13791400
public <T> ApiResponse<T> invokeAPI(String path, String method, List<Pair> queryParams, Object body, Map<String, String> headerParams, Map<String, String> cookieParams, Map<String, Object> formParams, String accept, String contentType, String[] authNames, GenericType<T> returnType, boolean isBodyNullable) throws ApiException {
1380-
return invokeAPI(null, path, method, queryParams, body, headerParams, cookieParams, formParams, accept, contentType, authNames, returnType, isBodyNullable);
1401+
return invokeAPI(null, path, method, queryParams, body, headerParams, cookieParams, formParams, accept, contentType, authNames, returnType, isBodyNullable, null/*TODO SME manage*/);
13811402
}
13821403
13831404
/**

modules/openapi-generator/src/main/resources/Java/libraries/jersey3/api.mustache

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,20 @@ public class {{classname}} {
195195
{{#hasAuthMethods}}
196196
String[] localVarAuthNames = {{=% %=}}new String[] {%#authMethods%"%name%"%^-last%, %/-last%%/authMethods%};%={{ }}=%
197197
{{/hasAuthMethods}}
198+
final Map<String, GenericType> localVarErrorTypes = new HashMap<String, GenericType>();
199+
{{#responses}}
200+
{{^-first}}
201+
{{#dataType}}
202+
localVarErrorTypes.put("{{code}}", new GenericType<{{{dataType}}}>() {});
203+
{{/dataType}}
204+
{{/-first}}
205+
{{/responses}}
198206
{{#returnType}}
199207
GenericType<{{{returnType}}}> localVarReturnType = new GenericType<{{{returnType}}}>() {};
200208
{{/returnType}}
201209
return apiClient.invokeAPI("{{classname}}.{{operationId}}", {{#hasPathParams}}localVarPath{{/hasPathParams}}{{^hasPathParams}}"{{{path}}}"{{/hasPathParams}}, "{{httpMethod}}", {{#queryParams}}{{#-first}}localVarQueryParams{{/-first}}{{/queryParams}}{{^queryParams}}new ArrayList<>(){{/queryParams}}, {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}null{{/bodyParam}},
202210
{{#headerParams}}{{#-first}}localVarHeaderParams{{/-first}}{{/headerParams}}{{^headerParams}}new LinkedHashMap<>(){{/headerParams}}, {{#cookieParams}}{{#-first}}localVarCookieParams{{/-first}}{{/cookieParams}}{{^cookieParams}}new LinkedHashMap<>(){{/cookieParams}}, {{#formParams}}{{#-first}}localVarFormParams{{/-first}}{{/formParams}}{{^formParams}}new LinkedHashMap<>(){{/formParams}}, localVarAccept, localVarContentType,
203-
{{#hasAuthMethods}}localVarAuthNames{{/hasAuthMethods}}{{^hasAuthMethods}}null{{/hasAuthMethods}}, {{#returnType}}localVarReturnType{{/returnType}}{{^returnType}}null{{/returnType}}, {{#bodyParam}}{{#isNullable}}true{{/isNullable}}{{^isNullable}}false{{/isNullable}}{{/bodyParam}}{{^bodyParam}}false{{/bodyParam}});
211+
{{#hasAuthMethods}}localVarAuthNames{{/hasAuthMethods}}{{^hasAuthMethods}}null{{/hasAuthMethods}}, {{#returnType}}localVarReturnType{{/returnType}}{{^returnType}}null{{/returnType}}, {{#bodyParam}}{{#isNullable}}true{{/isNullable}}{{^isNullable}}false{{/isNullable}}{{/bodyParam}}{{^bodyParam}}false{{/bodyParam}}, localVarErrorTypes);
204212
}
205213
{{#vendorExtensions.x-group-parameters}}
206214

modules/openapi-generator/src/main/resources/Java/libraries/jersey3/apiException.mustache

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class ApiException extends{{#useRuntimeException}} RuntimeException {{/us
2020
private int code = 0;
2121
private Map<String, List<String>> responseHeaders = null;
2222
private String responseBody = null;
23+
private Object errorEntity = null;
2324
2425
public ApiException() {}
2526

@@ -73,6 +74,11 @@ public class ApiException extends{{#useRuntimeException}} RuntimeException {{/us
7374
this.responseBody = responseBody;
7475
}
7576

77+
public ApiException(int code, String message, Map<String, List<String>> responseHeaders, String responseBody, Object errorEntity) {
78+
this(code, message, responseHeaders, responseBody);
79+
this.errorEntity = errorEntity;
80+
}
81+
7682
/**
7783
* Get the HTTP status code.
7884
*
@@ -99,4 +105,13 @@ public class ApiException extends{{#useRuntimeException}} RuntimeException {{/us
99105
public String getResponseBody() {
100106
return responseBody;
101107
}
108+
109+
/**
110+
* Get the deserialized error entity (or null if this error doesn't have a model associated).
111+
*
112+
* @return Deserialized error entity
113+
*/
114+
public Object getErrorEntity() {
115+
return errorEntity;
116+
}
102117
}

0 commit comments

Comments
 (0)