Skip to content

Commit 562310f

Browse files
[FSSDK-9127] fix: Handle ODP INVALID_IDENTIFIER_EXCEPTION code (#514)
* [FSSDK-9127] Fix: Verifiying that ODP INVALID_IDENTIFIER_EXCEPTION code is handled gracefully. * Parsed errors as per new odp update * support case when code key is missing and classification key exist. --------- Co-authored-by: NomanShoaib <m.nomanshoaib09@gmail.com>
1 parent 791ae41 commit 562310f

File tree

6 files changed

+65
-35
lines changed

6 files changed

+65
-35
lines changed

core-api/src/main/java/com/optimizely/ab/odp/parser/impl/GsonParser.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2022, Optimizely Inc. and contributors
2+
* Copyright 2022-2023, Optimizely Inc. and contributors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,15 +34,16 @@ public List<String> parseQualifiedSegments(String responseJson) {
3434
JsonObject root = JsonParser.parseString(responseJson).getAsJsonObject();
3535

3636
if (root.has("errors")) {
37-
JsonArray errors = root.getAsJsonArray("errors");
38-
StringBuilder logMessage = new StringBuilder();
39-
for (int i = 0; i < errors.size(); i++) {
40-
if (i > 0) {
41-
logMessage.append(", ");
37+
JsonArray errors = root.getAsJsonArray("errors");
38+
JsonObject extensions = errors.get(0).getAsJsonObject().get("extensions").getAsJsonObject();
39+
if (extensions != null) {
40+
if (extensions.has("code") && extensions.get("code").getAsString().equals("INVALID_IDENTIFIER_EXCEPTION")) {
41+
logger.warn("Audience segments fetch failed (invalid identifier)");
42+
} else {
43+
String errorMessage = extensions.get("classification") == null ? "decode error" : extensions.get("classification").getAsString();
44+
logger.error("Audience segments fetch failed (" + errorMessage + ")");
4245
}
43-
logMessage.append(errors.get(i).getAsJsonObject().get("message").getAsString());
4446
}
45-
logger.error(logMessage.toString());
4647
return null;
4748
}
4849

core-api/src/main/java/com/optimizely/ab/odp/parser/impl/JacksonParser.java

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2022, Optimizely Inc. and contributors
2+
* Copyright 2022-2023, Optimizely Inc. and contributors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,14 +39,15 @@ public List<String> parseQualifiedSegments(String responseJson) {
3939

4040
if (root.has("errors")) {
4141
JsonNode errors = root.path("errors");
42-
StringBuilder logMessage = new StringBuilder();
43-
for (int i = 0; i < errors.size(); i++) {
44-
if (i > 0) {
45-
logMessage.append(", ");
42+
JsonNode extensions = errors.get(0).path("extensions");
43+
if (extensions != null) {
44+
if (extensions.has("code") && extensions.path("code").asText().equals("INVALID_IDENTIFIER_EXCEPTION")) {
45+
logger.warn("Audience segments fetch failed (invalid identifier)");
46+
} else {
47+
String errorMessage = extensions.has("classification") ? extensions.path("classification").asText() : "decode error";
48+
logger.error("Audience segments fetch failed (" + errorMessage + ")");
4649
}
47-
logMessage.append(errors.get(i).path("message"));
4850
}
49-
logger.error(logMessage.toString());
5051
return null;
5152
}
5253

core-api/src/main/java/com/optimizely/ab/odp/parser/impl/JsonParser.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2022, Optimizely Inc. and contributors
2+
* Copyright 2022-2023, Optimizely Inc. and contributors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,15 +35,17 @@ public List<String> parseQualifiedSegments(String responseJson) {
3535
JSONObject root = new JSONObject(responseJson);
3636

3737
if (root.has("errors")) {
38-
JSONArray errors = root.getJSONArray("errors");
39-
StringBuilder logMessage = new StringBuilder();
40-
for (int i = 0; i < errors.length(); i++) {
41-
if (i > 0) {
42-
logMessage.append(", ");
38+
JSONArray errors = root.getJSONArray("errors");
39+
JSONObject extensions = errors.getJSONObject(0).getJSONObject("extensions");
40+
if (extensions != null) {
41+
if (extensions.has("code") && extensions.getString("code").equals("INVALID_IDENTIFIER_EXCEPTION")) {
42+
logger.warn("Audience segments fetch failed (invalid identifier)");
43+
} else {
44+
String errorMessage = extensions.has("classification") ?
45+
extensions.getString("classification") : "decode error";
46+
logger.error("Audience segments fetch failed (" + errorMessage + ")");
4347
}
44-
logMessage.append(errors.getJSONObject(i).getString("message"));
4548
}
46-
logger.error(logMessage.toString());
4749
return null;
4850
}
4951

core-api/src/main/java/com/optimizely/ab/odp/parser/impl/JsonSimpleParser.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2022, Optimizely Inc. and contributors
2+
* Copyright 2022-2023, Optimizely Inc. and contributors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,17 +36,17 @@ public List<String> parseQualifiedSegments(String responseJson) {
3636
JSONObject root = null;
3737
try {
3838
root = (JSONObject) parser.parse(responseJson);
39-
4039
if (root.containsKey("errors")) {
4140
JSONArray errors = (JSONArray) root.get("errors");
42-
StringBuilder logMessage = new StringBuilder();
43-
for (int i = 0; i < errors.size(); i++) {
44-
if (i > 0) {
45-
logMessage.append(", ");
41+
JSONObject extensions = (JSONObject) ((JSONObject) errors.get(0)).get("extensions");
42+
if (extensions != null) {
43+
if (extensions.containsKey("code") && extensions.get("code").equals("INVALID_IDENTIFIER_EXCEPTION")) {
44+
logger.warn("Audience segments fetch failed (invalid identifier)");
45+
} else {
46+
String errorMessage = extensions.get("classification") == null ? "decode error" : (String) extensions.get("classification");
47+
logger.error("Audience segments fetch failed (" + errorMessage + ")");
4648
}
47-
logMessage.append((String)((JSONObject) errors.get(i)).get("message"));
4849
}
49-
logger.error(logMessage.toString());
5050
return null;
5151
}
5252

core-api/src/test/java/com/optimizely/ab/odp/parser/ResponseJsonParserTest.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2022, Optimizely Inc. and contributors
2+
* Copyright 2022-2023, Optimizely Inc. and contributors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -84,9 +84,34 @@ public void returnNullWhenJsonIsMalformed() {
8484

8585
@Test
8686
public void returnNullAndLogCorrectErrorWhenErrorResponseIsReturned() {
87-
String responseToParse = "{\"errors\":[{\"message\":\"Exception while fetching data (/customer) : java.lang.RuntimeException: could not resolve _fs_user_id = wrong_id\",\"locations\":[{\"line\":2,\"column\":3}],\"path\":[\"customer\"],\"extensions\":{\"classification\":\"InvalidIdentifierException\"}}],\"data\":{\"customer\":null}}";
87+
String responseToParse = "{\"errors\":[{\"message\":\"Exception while fetching data (/customer) : java.lang.RuntimeException: could not resolve _fs_user_id = wrong_id\",\"locations\":[{\"line\":2,\"column\":3}],\"path\":[\"customer\"],\"extensions\":{\"code\":\"INVALID_IDENTIFIER_EXCEPTION\", \"classification\":\"DataFetchingException\"}}],\"data\":{\"customer\":null}}";
8888
List<String> parsedSegments = jsonParser.parseQualifiedSegments(responseToParse);
89-
logbackVerifier.expectMessage(Level.ERROR, "Exception while fetching data (/customer) : java.lang.RuntimeException: could not resolve _fs_user_id = wrong_id");
89+
logbackVerifier.expectMessage(Level.WARN, "Audience segments fetch failed (invalid identifier)");
9090
assertEquals(null, parsedSegments);
9191
}
92+
93+
@Test
94+
public void returnNullAndLogNoErrorWhenErrorResponseIsReturnedButCodeKeyIsNotPresent() {
95+
String responseToParse = "{\"errors\":[{\"message\":\"Exception while fetching data (/customer) : java.lang.RuntimeException: could not resolve _fs_user_id = wrong_id\",\"locations\":[{\"line\":2,\"column\":3}],\"path\":[\"customer\"],\"extensions\":{\"classification\":\"DataFetchingException\"}}],\"data\":{\"customer\":null}}";
96+
List<String> parsedSegments = jsonParser.parseQualifiedSegments(responseToParse);
97+
logbackVerifier.expectMessage(Level.ERROR, "Audience segments fetch failed (DataFetchingException)");
98+
assertEquals(null, parsedSegments);
99+
}
100+
101+
@Test
102+
public void returnNullAndLogCorrectErrorWhenErrorResponseIsReturnedButCodeValueIsNotInvalidIdentifierException() {
103+
String responseToParse = "{\"errors\":[{\"message\":\"Exception while fetching data (/customer) : java.lang.RuntimeException: could not resolve _fs_user_id = wrong_id\",\"locations\":[{\"line\":2,\"column\":3}],\"path\":[\"customer\"],\"extensions\":{\"code\":\"OTHER_EXCEPTIONS\", \"classification\":\"DataFetchingException\"}}],\"data\":{\"customer\":null}}";
104+
List<String> parsedSegments = jsonParser.parseQualifiedSegments(responseToParse);
105+
logbackVerifier.expectMessage(Level.ERROR, "Audience segments fetch failed (DataFetchingException)");
106+
assertEquals(null, parsedSegments);
107+
}
108+
109+
@Test
110+
public void returnNullAndLogCorrectErrorWhenErrorResponseIsReturnedButCodeValueIsNotInvalidIdentifierExceptionNullClassification() {
111+
String responseToParse = "{\"errors\":[{\"message\":\"Exception while fetching data (/customer) : java.lang.RuntimeException: could not resolve _fs_user_id = wrong_id\",\"locations\":[{\"line\":2,\"column\":3}],\"path\":[\"customer\"],\"extensions\":{\"code\":\"OTHER_EXCEPTIONS\"}}],\"data\":{\"customer\":null}}";
112+
List<String> parsedSegments = jsonParser.parseQualifiedSegments(responseToParse);
113+
logbackVerifier.expectMessage(Level.ERROR, "Audience segments fetch failed (decode error)");
114+
assertEquals(null, parsedSegments);
115+
}
116+
92117
}

core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ String getSegmentsStringForRequest(Set<String> segmentsList) {
137137
"customer"
138138
],
139139
"extensions": {
140-
"classification": "InvalidIdentifierException"
140+
"code": "INVALID_IDENTIFIER_EXCEPTION",
141+
"classification": "DataFetchingException"
141142
}
142143
}
143144
],

0 commit comments

Comments
 (0)