Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,7 @@ public void processOpts() {
// one by one for each library.
supportsAdditionalPropertiesWithComposedSchema = true;
} else if (libWebClient) {
supportingFiles.add(new SupportingFile("ExceptionProvider.mustache", invokerFolder, "ExceptionProvider.java"));
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);

// Composed schemas can have the 'additionalProperties' keyword, as specified in JSON schema.
Expand All @@ -729,6 +730,7 @@ public void processOpts() {
// one by one for each library.
supportsAdditionalPropertiesWithComposedSchema = true;
} else if (libRestClient) {
supportingFiles.add(new SupportingFile("ExceptionProvider.mustache", invokerFolder, "ExceptionProvider.java"));
forceSerializationLibrary(SERIALIZATION_LIBRARY_JACKSON);
applyJakartaPackage();

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{{>licenseInfo}}

package {{invokerPackage}};

import org.springframework.web.client.RestClientException;
import java.text.ParseException;

/**
* Extension point for customizing exceptions thrown by the generated API client.
* <p>
* The default implementation throws {@link RuntimeException}. To use custom exception
* types, implement this interface and pass the instance to
* {@link ApiClient#setExceptionProvider(ExceptionProvider)}.
* </p>
* <pre>{@code
* apiClient.setExceptionProvider(new ExceptionProvider() {
* public RuntimeException bearerAuthException() {
* return new MyAuthException("No Bearer authentication configured!");
* }
* });
* }</pre>
*/
public interface ExceptionProvider {

/** Returns an exception indicating that no Bearer authentication is configured. */
default RuntimeException bearerAuthException() {
return new RuntimeException("No Bearer authentication configured!");
}

/** Returns an exception indicating that no HTTP basic authentication is configured. */
default RuntimeException httpBasicAuthException() {
return new RuntimeException("No HTTP basic authentication configured!");
}

/** Returns an exception indicating that no API key authentication is configured. */
default RuntimeException apiKeyAuthException() {
return new RuntimeException("No API key authentication configured!");
}

/** Returns an exception indicating that no OAuth2 authentication is configured. */
default RuntimeException oAuth2Exception() {
return new RuntimeException("No OAuth2 authentication configured!");
}

/** Wraps a date/time parse exception. */
default RuntimeException dateTimeException(ParseException e) {
return new RuntimeException(e);
}

/** Wraps a Jackson serialization/deserialization exception. */
default RuntimeException jacksonException(Exception e) {
return new RuntimeException(e);
}

/**
* Returns an exception indicating that the requested authentication scheme is not configured.
*
* @param authName the name of the authentication scheme that could not be found
* @return a {@link RestClientException} describing the missing authentication
*/
default RestClientException undefinedAuthenticationException(String authName) {
Comment thread
Mattias-Sehlstedt marked this conversation as resolved.
return new RestClientException("Authentication undefined: " + authName);
}

/** The default {@link ExceptionProvider} instance. */
ExceptionProvider DEFAULT = new ExceptionProvider() {};

}
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
{{/useJackson3}}
protected Map<String, Authentication> authentications;

/**
* The {@link ExceptionProvider} used to create exceptions thrown by this client.
* Defaults to {@link ExceptionProvider#DEFAULT}. Can be replaced to customize the exceptions
* thrown by this client by calling {@link #setExceptionProvider(ExceptionProvider)}.
*/
protected ExceptionProvider exceptionProvider = ExceptionProvider.DEFAULT;


public ApiClient() {
this(null);
Expand Down Expand Up @@ -351,6 +358,25 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return authentications;
}

/**
* Get the current {@link ExceptionProvider}.
* @return the exception provider
*/
public ExceptionProvider getExceptionProvider() {
return exceptionProvider;
}

/**
* Set a custom {@link ExceptionProvider} to control which exception types are thrown
* by this client.
* @param exceptionProvider the exception provider
* @return this client instance
*/
public ApiClient setExceptionProvider(ExceptionProvider exceptionProvider) {
this.exceptionProvider = exceptionProvider;
return this;
}

/**
* Get authentication for the given name.
*
Expand All @@ -372,7 +398,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return;
}
}
throw new RuntimeException("No Bearer authentication configured!");
throw exceptionProvider.bearerAuthException();
}

/**
Expand All @@ -387,7 +413,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return;
}
}
throw new RuntimeException("No Bearer authentication configured!");
throw exceptionProvider.bearerAuthException();
}

/**
Expand All @@ -401,7 +427,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return;
}
}
throw new RuntimeException("No HTTP basic authentication configured!");
throw exceptionProvider.httpBasicAuthException();
}

/**
Expand All @@ -415,7 +441,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return;
}
}
throw new RuntimeException("No HTTP basic authentication configured!");
throw exceptionProvider.httpBasicAuthException();
}

/**
Expand All @@ -429,7 +455,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return;
}
}
throw new RuntimeException("No API key authentication configured!");
throw exceptionProvider.apiKeyAuthException();
}

/**
Expand All @@ -443,7 +469,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return;
}
}
throw new RuntimeException("No API key authentication configured!");
throw exceptionProvider.apiKeyAuthException();
}

{{#hasOAuthMethods}}
Expand All @@ -468,7 +494,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return this;
}
}
throw new RuntimeException("No OAuth2 authentication configured!");
throw exceptionProvider.oAuth2Exception();
}

{{/hasOAuthMethods}}
Expand Down Expand Up @@ -524,7 +550,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
try {
return dateFormat.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
throw exceptionProvider.dateTimeException(e);
}
}

Expand Down Expand Up @@ -592,7 +618,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
try {
return parameterToMultiValueMap(collectionFormat, name, mapper.writeValueAsString(value));
} catch ({{#useJackson3}}JacksonException{{/useJackson3}}{{^useJackson3}}JsonProcessingException{{/useJackson3}} e) {
throw new RuntimeException(e);
throw exceptionProvider.jacksonException(e);
}
}

Expand All @@ -601,7 +627,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
try {
values.add(mapper.writeValueAsString(o));
} catch ({{#useJackson3}}JacksonException{{/useJackson3}}{{^useJackson3}}JsonProcessingException{{/useJackson3}} e) {
throw new RuntimeException(e);
throw exceptionProvider.jacksonException(e);
}
}
return parameterToMultiValueMap(collectionFormat, name, "[" + StringUtils.collectionToDelimitedString(values, collectionFormat.separator) + "]");
Expand Down Expand Up @@ -935,7 +961,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
for (String authName : authNames) {
Authentication auth = authentications.get(authName);
if (auth == null) {
throw new RestClientException("Authentication undefined: " + authName);
throw exceptionProvider.undefinedAuthenticationException(authName);
}
auth.applyToParams(queryParams, headerParams, cookieParams);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,13 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {

protected Map<String, Authentication> authentications;

/**
* The {@link ExceptionProvider} used to create exceptions thrown by this client.
* Defaults to {@link ExceptionProvider#DEFAULT}. Can be replaced to customize the exceptions
* thrown by this client by calling {@link #setExceptionProvider(ExceptionProvider)}.
*/
protected ExceptionProvider exceptionProvider = ExceptionProvider.DEFAULT;


public ApiClient() {
this.dateFormat = createDefaultDateFormat();
Expand Down Expand Up @@ -287,6 +294,25 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return authentications;
}

/**
* Get the current {@link ExceptionProvider}.
* @return the exception provider
*/
public ExceptionProvider getExceptionProvider() {
return exceptionProvider;
}

/**
* Set a custom {@link ExceptionProvider} to control which exception types are thrown
* by this client.
* @param exceptionProvider the exception provider
* @return this client instance
*/
public ApiClient setExceptionProvider(ExceptionProvider exceptionProvider) {
this.exceptionProvider = exceptionProvider;
return this;
}

/**
* Get authentication for the given name.
*
Expand All @@ -308,7 +334,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return;
}
}
throw new RuntimeException("No Bearer authentication configured!");
throw exceptionProvider.bearerAuthException();
}

/**
Expand All @@ -322,7 +348,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return;
}
}
throw new RuntimeException("No HTTP basic authentication configured!");
throw exceptionProvider.httpBasicAuthException();
}

/**
Expand All @@ -336,7 +362,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return;
}
}
throw new RuntimeException("No HTTP basic authentication configured!");
throw exceptionProvider.httpBasicAuthException();
}

/**
Expand All @@ -350,7 +376,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return;
}
}
throw new RuntimeException("No API key authentication configured!");
throw exceptionProvider.apiKeyAuthException();
}

/**
Expand All @@ -364,7 +390,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return;
}
}
throw new RuntimeException("No API key authentication configured!");
throw exceptionProvider.apiKeyAuthException();
}

{{#hasOAuthMethods}}
Expand All @@ -379,7 +405,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
return;
}
}
throw new RuntimeException("No OAuth2 authentication configured!");
throw exceptionProvider.oAuth2Exception();
}

{{/hasOAuthMethods}}
Expand Down Expand Up @@ -435,7 +461,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
try {
return dateFormat.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
throw exceptionProvider.dateTimeException(e);
}
}

Expand Down Expand Up @@ -502,8 +528,8 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
} else {
try {
return parameterToMultiValueMap(collectionFormat, name, mapper.writeValueAsString(value));
} catch ({{#useJackson3}}JacksonException{{/useJackson3}}{{^useJackson3}}JsonProcessingException{{/useJackson3}} e) {
throw new RuntimeException(e);
} catch ({{#useJackson3}}JacksonException{{/useJackson3}}{{^useJackson3}}JsonProcessingException{{/useJackson3}} e) {
throw exceptionProvider.jacksonException(e);
}
}

Expand All @@ -512,7 +538,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
try {
values.add(mapper.writeValueAsString(o));
} catch ({{#useJackson3}}JacksonException{{/useJackson3}}{{^useJackson3}}JsonProcessingException{{/useJackson3}} e) {
throw new RuntimeException(e);
throw exceptionProvider.jacksonException(e);
}
}
return parameterToMultiValueMap(collectionFormat, name, "[" + StringUtils.collectionToDelimitedString(values, collectionFormat.separator) + "]");
Expand Down Expand Up @@ -821,7 +847,7 @@ public class ApiClient{{#jsr310}} extends JavaTimeFormatter{{/jsr310}} {
for (String authName : authNames) {
Authentication auth = authentications.get(authName);
if (auth == null) {
throw new RestClientException("Authentication undefined: " + authName);
throw exceptionProvider.undefinedAuthenticationException(authName);
}
auth.applyToParams(queryParams, headerParams, cookieParams);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pom.xml
settings.gradle
src/main/AndroidManifest.xml
src/main/java/org/openapitools/client/ApiClient.java
src/main/java/org/openapitools/client/ExceptionProvider.java
src/main/java/org/openapitools/client/JavaTimeFormatter.java
src/main/java/org/openapitools/client/RFC3339DateFormat.java
src/main/java/org/openapitools/client/RFC3339InstantDeserializer.java
Expand Down
Loading
Loading