Skip to content

Commit 6eac172

Browse files
authored
Merge pull request #123 from auth0/add-exception-getter
Expose additional error response properties in the Exception
2 parents 0b5ba38 + 8ae7239 commit 6eac172

5 files changed

Lines changed: 53 additions & 6 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ If you need to handle different error scenarios you need to catch first `APIExce
526526

527527
The APIExplorer includes a list of response messages for each endpoint. You can get a clue of what went wrong by asking the Http status code: `exception.getStatusCode()`. i.e. a `status_code=403` would mean that the token has an insufficient scope.
528528

529-
An error code will be included to categorize the type of error, you can get it by calling `exception.getError()`. If you want to see a user friendly description of what happened and why the request is failing check the `exception.getDescription()`.
529+
An error code will be included to categorize the type of error, you can get it by calling `exception.getError()`. If you want to see a user friendly description of what happened and why the request is failing check the `exception.getDescription()`. Finally, if the error response includes additional properties they can be obtained by calling `exception.getValue("{THE_KEY}")`.
530530

531531

532532
```

src/main/java/com/auth0/exception/APIException.java

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.auth0.exception;
22

3+
import java.util.Collections;
34
import java.util.Map;
45

56
/**
@@ -21,6 +22,7 @@ public class APIException extends Auth0Exception {
2122
private String error;
2223
private String description;
2324
private int statusCode;
25+
private Map<String, Object> values;
2426

2527
public APIException(String payload, int statusCode, Throwable cause) {
2628
super(createMessage(payload, statusCode), cause);
@@ -30,8 +32,9 @@ public APIException(String payload, int statusCode, Throwable cause) {
3032

3133
public APIException(Map<String, Object> values, int statusCode) {
3234
super(createMessage(obtainExceptionMessage(values), statusCode));
33-
this.error = obtainExceptionError(values);
34-
this.description = obtainExceptionMessage(values);
35+
this.values = Collections.unmodifiableMap(values);
36+
this.error = obtainExceptionError(this.values);
37+
this.description = obtainExceptionMessage(this.values);
3538
this.statusCode = statusCode;
3639
}
3740

@@ -55,6 +58,19 @@ public String getError() {
5558
return error;
5659
}
5760

61+
/**
62+
* Returns a value from the error map, if any.
63+
*
64+
* @param key key of the value to return
65+
* @return the value if found or null
66+
*/
67+
public Object getValue(String key) {
68+
if (values == null) {
69+
return null;
70+
}
71+
return values.get(key);
72+
}
73+
5874
/**
5975
* Getter for the exception user friendly description of why the request failed.
6076
* i.e. the description may say which query parameters are valid for that endpoint.
@@ -75,9 +91,9 @@ private static String obtainExceptionMessage(Map<String, Object> values) {
7591
}
7692
if (values.containsKey("description")) {
7793
Object description = values.get("description");
78-
if(description instanceof String) {
94+
if (description instanceof String) {
7995
return (String) description;
80-
} else{
96+
} else {
8197
PasswordStrengthErrorParser policy = new PasswordStrengthErrorParser((Map<String, Object>) description);
8298
return policy.getDescription();
8399
}

src/test/java/com/auth0/client/MockServer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class MockServer {
2323
public static final String AUTH_ERROR_WITH_ERROR_DESCRIPTION = "src/test/resources/auth/error_with_error_description.json";
2424
public static final String AUTH_ERROR_WITH_ERROR = "src/test/resources/auth/error_with_error.json";
2525
public static final String AUTH_ERROR_WITH_DESCRIPTION = "src/test/resources/auth/error_with_description.json";
26+
public static final String AUTH_ERROR_WITH_DESCRIPTION_AND_EXTRA_PROPERTIES = "src/test/resources/auth/error_with_description_and_extra_properties.json";
2627
public static final String AUTH_ERROR_PLAINTEXT = "src/test/resources/auth/error_plaintext.json";
2728
public static final String MGMT_ERROR_WITH_MESSAGE = "src/test/resources/mgmt/error_with_message.json";
2829
public static final String MGMT_CLIENT_GRANTS_LIST = "src/test/resources/mgmt/client_grants_list.json";

src/test/java/com/auth0/net/CustomRequestTest.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package com.auth0.net;
22

33
import com.auth0.client.MockServer;
4-
import com.auth0.exception.Auth0Exception;
54
import com.auth0.exception.APIException;
5+
import com.auth0.exception.Auth0Exception;
66
import com.auth0.json.auth.TokenHolder;
77
import com.fasterxml.jackson.core.JsonParseException;
88
import com.fasterxml.jackson.core.JsonProcessingException;
@@ -214,6 +214,30 @@ public void shouldParseJSONErrorResponseWithError() throws Exception {
214214
assertThat(authException.getStatusCode(), is(400));
215215
}
216216

217+
@SuppressWarnings("RedundantCast")
218+
@Test
219+
public void shouldParseJSONErrorResponseWithDescriptionAndExtraProperties() throws Exception {
220+
CustomRequest<List> request = new CustomRequest<>(client, server.getBaseUrl(), "GET", listType);
221+
server.jsonResponse(AUTH_ERROR_WITH_DESCRIPTION_AND_EXTRA_PROPERTIES, 400);
222+
Exception exception = null;
223+
try {
224+
request.execute();
225+
server.takeRequest();
226+
} catch (Exception e) {
227+
exception = e;
228+
}
229+
assertThat(exception, is(notNullValue()));
230+
assertThat(exception, is(instanceOf(APIException.class)));
231+
assertThat(exception.getCause(), is(nullValue()));
232+
assertThat(exception.getMessage(), is("Request failed with status code 400: Multifactor authentication required"));
233+
APIException authException = (APIException) exception;
234+
assertThat(authException.getDescription(), is("Multifactor authentication required"));
235+
assertThat(authException.getError(), is("mfa_required"));
236+
assertThat(authException.getValue("mfa_token"), is((Object) "Fe26...Ha"));
237+
assertThat(authException.getValue("non_existing_key"), is(nullValue()));
238+
assertThat(authException.getStatusCode(), is(400));
239+
}
240+
217241
@Test
218242
public void shouldParseJSONErrorResponseWithDescription() throws Exception {
219243
CustomRequest<List> request = new CustomRequest<>(client, server.getBaseUrl(), "GET", listType);
@@ -274,6 +298,7 @@ public void shouldParsePlainTextErrorResponse() throws Exception {
274298
APIException authException = (APIException) exception;
275299
assertThat(authException.getDescription(), is("A plain-text error response"));
276300
assertThat(authException.getError(), is(nullValue()));
301+
assertThat(authException.getValue("non_existing_key"), is(nullValue()));
277302
assertThat(authException.getStatusCode(), is(400));
278303
}
279304

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"error": "mfa_required",
3+
"error_description": "Multifactor authentication required",
4+
"mfa_token": "Fe26...Ha"
5+
}

0 commit comments

Comments
 (0)