Skip to content

Commit 2eff1d1

Browse files
authored
Merge pull request #176 from StillGreen-san/onedrive-improvements
onedrive improvements
2 parents 35c2b14 + 0051e1d commit 2eff1d1

File tree

2 files changed

+432
-238
lines changed

2 files changed

+432
-238
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package ratismal.drivebackup.uploaders.onedrive;
2+
3+
import okhttp3.Response;
4+
import org.jetbrains.annotations.NotNull;
5+
import org.jetbrains.annotations.Nullable;
6+
import org.json.JSONArray;
7+
import org.json.JSONObject;
8+
import org.json.JSONException;
9+
10+
import java.io.IOException;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import java.util.stream.Collectors;
14+
15+
/**
16+
* an exception representing a microsoft graph api error
17+
*/
18+
public class GraphApiErrorException extends Exception {
19+
private static final String ERROR_OBJ_KEY = "error";
20+
private static final String CODE_STR_KEY = "code";
21+
private static final String INNERERROR_OBJ_KEY = "innererror";
22+
private static final String MESSAGE_STR_KEY = "message";
23+
private static final String DETAILS_ARR_KEY = "details";
24+
25+
/** status code of the response or -1 if not available */
26+
public final int statusCode;
27+
/** an error code string for the error that occurred */
28+
public final String errorCode;
29+
/** a developer ready message about the error that occurred. this shouldn't be displayed to the user directly */
30+
public final String errorMessage;
31+
/** optional list of additional error objects that might be more specific than the top-level error */
32+
public final List<String> innerErrors;
33+
/**
34+
* optional list of additional error objects that might provide a breakdown of multiple errors encountered
35+
* while processing the request
36+
*/
37+
public final List<GraphApiErrorException> details;
38+
39+
/**
40+
* create the exception from a response
41+
*
42+
* @param response to parse error from its body
43+
* @throws IOException if the body string could not be loaded
44+
* @throws NullPointerException if the body could not be loaded
45+
* @throws JSONException if the body does not contain the expected json values
46+
*/
47+
public GraphApiErrorException(@NotNull Response response) throws IOException {
48+
this(response.code(), new JSONObject(response.body().string()).getJSONObject(ERROR_OBJ_KEY));
49+
}
50+
51+
/**
52+
* create the exception from a status code and response body
53+
*
54+
* @param statusCode of the response
55+
* @param responseBody of the response
56+
* @throws JSONException if the body does not contain the expected json values
57+
*/
58+
public GraphApiErrorException(int statusCode, @NotNull String responseBody) {
59+
this(statusCode, new JSONObject(responseBody).getJSONObject(ERROR_OBJ_KEY));
60+
}
61+
62+
private static List<String> parseInnerErrors(@Nullable JSONObject innerErrors) {
63+
List<String> list = new ArrayList<>();
64+
while (innerErrors != null) {
65+
String errorCode = innerErrors.optString(CODE_STR_KEY);
66+
if (errorCode != null) {
67+
list.add(errorCode);
68+
}
69+
innerErrors = innerErrors.optJSONObject(INNERERROR_OBJ_KEY);
70+
}
71+
return list;
72+
}
73+
74+
private static List<GraphApiErrorException> parseDetails(@Nullable JSONArray details) {
75+
if (details == null) {
76+
return new ArrayList<>();
77+
}
78+
List<GraphApiErrorException> list = new ArrayList<>(details.length());
79+
for (int detailIdx = 0; detailIdx < details.length(); detailIdx++) {
80+
list.add(new GraphApiErrorException(-1, details.getJSONObject(detailIdx).getJSONObject(ERROR_OBJ_KEY)));
81+
}
82+
return list;
83+
}
84+
85+
private GraphApiErrorException(int statusCode, @NotNull JSONObject error) {
86+
this(statusCode, error.getString(CODE_STR_KEY), error.getString(MESSAGE_STR_KEY),
87+
parseInnerErrors(error.optJSONObject(INNERERROR_OBJ_KEY)),
88+
parseDetails(error.optJSONArray(DETAILS_ARR_KEY)));
89+
}
90+
91+
private static String toMessage(int statusCode, String errorCode, String errorMessage, List<String> innerErrors,
92+
List<GraphApiErrorException> details) {
93+
String format = "%d %s : \"%s\"%s%s";
94+
String inner = String.join("\", \"", innerErrors);
95+
String detail = details.stream().map(GraphApiErrorException::getMessage).collect(Collectors.joining(" }, { "));
96+
if (!inner.isEmpty()) {
97+
inner = " inner:[ \"" + inner + "\" ]";
98+
}
99+
if (!detail.isEmpty()) {
100+
detail = " details:[ { " + detail + " } ]";
101+
}
102+
return String.format(format, statusCode, errorCode, errorMessage, inner, detail);
103+
}
104+
105+
private GraphApiErrorException(int statusCode, String errorCode, String errorMessage, List<String> innerErrors,
106+
List<GraphApiErrorException> details) {
107+
super(toMessage(statusCode, errorCode, errorMessage, innerErrors, details));
108+
this.statusCode = statusCode;
109+
this.errorCode = errorCode;
110+
this.errorMessage = errorMessage;
111+
this.innerErrors = innerErrors;
112+
this.details = details;
113+
}
114+
}

0 commit comments

Comments
 (0)