Skip to content

Commit a5583bc

Browse files
author
Caitlin Bales (MSFT)
authored
Merge pull request #16 from microsoftgraph/errors
Improved error handling
2 parents 075c660 + 8318c52 commit a5583bc

16 files changed

+140
-80
lines changed

src/main/java/com/microsoft/graph/concurrency/ChunkedUploadResponseHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ public ChunkedUploadResult generateResult(
108108

109109
return new ChunkedUploadResult(
110110
GraphServiceException.createFromConnection(request, null, serializer,
111-
connection));
111+
connection, logger));
112112
}
113113
} finally {
114114
if (in != null) {

src/main/java/com/microsoft/graph/core/ClientException.java

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,28 +27,13 @@
2727
*/
2828
public class ClientException extends RuntimeException {
2929

30-
/**
31-
* The error code for this exception.
32-
*/
33-
private final GraphErrorCodes errorCode;
34-
3530
/**
3631
* Creates the client exception.
3732
* @param message The message to display.
3833
* @param ex The exception from.
3934
* @param errorCode The error code for this exception.
4035
*/
41-
public ClientException(final String message, final Throwable ex, final GraphErrorCodes errorCode) {
36+
public ClientException(final String message, final Throwable ex) {
4237
super(message, ex);
43-
this.errorCode = errorCode;
44-
}
45-
46-
/**
47-
* Determines if the given error code is expected.
48-
* @param expectedCode The expected error code.
49-
* @return true if the error code matches, and false if there was no match.
50-
*/
51-
public boolean isError(final GraphErrorCodes expectedCode) {
52-
return this.errorCode == expectedCode;
5338
}
5439
}

src/main/java/com/microsoft/graph/http/BaseRequest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,13 @@ public URL getRequestUrl() {
153153
try {
154154
return new URL(uriBuilder.build().toString());
155155
} catch (final MalformedURLException e) {
156-
throw new ClientException("Invalid URL: " + uriBuilder.toString(), e, GraphErrorCodes.INVALID_REQUEST);
156+
if (this instanceof CustomRequest) {
157+
this.getClient().getLogger().logError("Invalid custom URL: " + uriBuilder.toString(), e);
158+
} else {
159+
throw new ClientException("Invalid URL: " + uriBuilder.toString(), e);
160+
}
157161
}
162+
return null;
158163
}
159164

160165
private String addFunctionParameters() {

src/main/java/com/microsoft/graph/http/DefaultHttpProvider.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,12 +332,11 @@ private <Result, Body, DeserializeType> Result sendRequestInternal(final IHttpRe
332332
}
333333
} catch (final GraphServiceException ex) {
334334
final boolean shouldLogVerbosely = logger.getLoggingLevel() == LoggerLevel.DEBUG;
335-
logger.logError("OneDrive Service exception " + ex.getMessage(shouldLogVerbosely), ex);
335+
logger.logError("Graph service exception " + ex.getMessage(shouldLogVerbosely), ex);
336336
throw ex;
337337
} catch (final Exception ex) {
338338
final ClientException clientException = new ClientException("Error during http request",
339-
ex,
340-
GraphErrorCodes.GENERAL_EXCEPTION);
339+
ex);
341340
logger.logError("Error during http request", clientException);
342341
throw clientException;
343342
}
@@ -357,7 +356,7 @@ private <Body> void handleErrorResponse(final IHttpRequest request,
357356
final IConnection connection)
358357
throws IOException {
359358
throw GraphServiceException.createFromConnection(request, serializable, serializer,
360-
connection);
359+
connection, logger);
361360
}
362361

363362
/**

src/main/java/com/microsoft/graph/http/GraphFatalServiceException.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@
2929
*/
3030
public class GraphFatalServiceException extends GraphServiceException {
3131

32-
/**
33-
* The web site to report issues on this SDK.
34-
*/
35-
public static final String SDK_BUG_URL = "https://github.com/microsoftgraph/msgraph-sdk-java/issues";
36-
3732
/**
3833
* Create a fatal Graph service exception.
3934
* @param method The method that caused the exception.
@@ -52,19 +47,17 @@ protected GraphFatalServiceException(final String method,
5247
final int responseCode,
5348
final String responseMessage,
5449
final List<String> responseHeaders,
55-
final GraphErrorResponse error) {
56-
super(method, url, requestHeaders, requestBody, responseCode, responseMessage, responseHeaders, error);
50+
final GraphErrorResponse error,
51+
final boolean verbose) {
52+
super(method, url, requestHeaders, requestBody, responseCode, responseMessage, responseHeaders, error, verbose);
5753
}
5854

5955
@Override
6056
public String getMessage(final boolean verbose) {
6157
//no inspection StringBufferReplaceableByString
6258
final StringBuilder sb = new StringBuilder();
63-
sb.append("[This is an unexpected error from Graph, please report this at ")
64-
.append(SDK_BUG_URL)
65-
.append(']')
66-
.append(NEW_LINE)
67-
.append(super.getMessage(true));
59+
sb.append("Unexpected exception returned from the service.")
60+
.append(super.getMessage(verbose));
6861
return sb.toString();
6962
}
7063
}

src/main/java/com/microsoft/graph/http/GraphServiceException.java

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import com.google.gson.GsonBuilder;
3333
import com.microsoft.graph.core.ClientException;
3434
import com.microsoft.graph.core.GraphErrorCodes;
35+
import com.microsoft.graph.logger.ILogger;
36+
import com.microsoft.graph.logger.LoggerLevel;
3537
import com.microsoft.graph.options.HeaderOption;
3638
import com.microsoft.graph.serializer.ISerializer;
3739

@@ -104,6 +106,11 @@ public class GraphServiceException extends ClientException {
104106
* The response headers.
105107
*/
106108
private final List<String> responseHeaders;
109+
110+
/**
111+
* Whether to log the full error response.
112+
*/
113+
private final boolean verbose;
107114

108115
/**
109116
* Create a Graph service exception.
@@ -116,6 +123,7 @@ public class GraphServiceException extends ClientException {
116123
* @param responseMessage The response message.
117124
* @param responseHeaders The response headers.
118125
* @param error The error response if available.
126+
* @param verbose The error response log level.
119127
*/
120128
protected GraphServiceException(final String method,
121129
final String url,
@@ -124,8 +132,9 @@ protected GraphServiceException(final String method,
124132
final int responseCode,
125133
final String responseMessage,
126134
final List<String> responseHeaders,
127-
final GraphErrorResponse error) {
128-
super(responseMessage, null, null);
135+
final GraphErrorResponse error,
136+
final boolean verbose) {
137+
super(responseMessage, null);
129138
this.method = method;
130139
this.url = url;
131140
this.requestHeaders = requestHeaders;
@@ -134,11 +143,12 @@ protected GraphServiceException(final String method,
134143
this.responseMessage = responseMessage;
135144
this.responseHeaders = responseHeaders;
136145
this.error = error;
146+
this.verbose = verbose;
137147
}
138148

139149
@Override
140150
public String getMessage() {
141-
return getMessage(false);
151+
return getMessage(verbose);
142152
}
143153

144154
/**
@@ -201,8 +211,10 @@ public String getMessage(final boolean verbose) {
201211
sb.append("[Warning: Unable to parse error message body]").append(NEW_LINE);
202212
}
203213
} else {
204-
sb.append(TRUNCATION_MARKER).append(NEW_LINE).append(NEW_LINE);
205-
sb.append("[Some information was truncated for brevity, enable debug logging for more details]");
214+
if (!verbose) {
215+
sb.append(TRUNCATION_MARKER).append(NEW_LINE).append(NEW_LINE);
216+
sb.append("[Some information was truncated for brevity, enable debug logging for more details]");
217+
}
206218
}
207219
return sb.toString();
208220
}
@@ -216,14 +228,6 @@ public GraphError getServiceError() {
216228
return error.error;
217229
}
218230

219-
@Override
220-
public boolean isError(final GraphErrorCodes expectedCode) {
221-
if (getServiceError() != null) {
222-
return getServiceError().isError(expectedCode);
223-
}
224-
return false;
225-
}
226-
227231
/**
228232
* Creates a Graph service exception from a given failed HTTP request.
229233
*
@@ -238,26 +242,32 @@ public boolean isError(final GraphErrorCodes expectedCode) {
238242
public static <T> GraphServiceException createFromConnection(final IHttpRequest request,
239243
final T serializable,
240244
final ISerializer serializer,
241-
final IConnection connection)
245+
final IConnection connection,
246+
final ILogger logger)
242247
throws IOException {
243248
final String method = connection.getRequestMethod();
244249
final String url = request.getRequestUrl().toString();
245250
final List<String> requestHeaders = new LinkedList<>();
246251
for (final HeaderOption option : request.getHeaders()) {
247252
requestHeaders.add(option.getName() + " : " + option.getValue());
248253
}
254+
boolean isVerbose = logger.getLoggingLevel() == LoggerLevel.DEBUG;
249255
final String requestBody;
250256
if (serializable instanceof byte[]) {
251257
final byte[] bytes = (byte[]) serializable;
252258
StringBuilder sb = new StringBuilder();
253259
sb.append("byte[").append(bytes.length).append("]");
254260

255261
sb.append(" {");
256-
for (int i = 0; i < MAX_BYTE_COUNT_BEFORE_TRUNCATION && i < bytes.length; i++) {
257-
sb.append(bytes[i]).append(", ");
258-
}
259-
if (bytes.length > MAX_BYTE_COUNT_BEFORE_TRUNCATION) {
260-
sb.append(TRUNCATION_MARKER).append("}");
262+
if (isVerbose) {
263+
sb.append(bytes);
264+
} else {
265+
for (int i = 0; i < MAX_BYTE_COUNT_BEFORE_TRUNCATION && i < bytes.length; i++) {
266+
sb.append(bytes[i]).append(", ");
267+
}
268+
if (bytes.length > MAX_BYTE_COUNT_BEFORE_TRUNCATION) {
269+
sb.append(TRUNCATION_MARKER).append("}");
270+
}
261271
}
262272
requestBody = sb.toString();
263273
} else if (serializable != null) {
@@ -301,7 +311,8 @@ public static <T> GraphServiceException createFromConnection(final IHttpRequest
301311
responseCode,
302312
responseMessage,
303313
responseHeaders,
304-
error);
314+
error,
315+
isVerbose);
305316
}
306317

307318
return new GraphServiceException(method,
@@ -311,6 +322,7 @@ public static <T> GraphServiceException createFromConnection(final IHttpRequest
311322
responseCode,
312323
responseMessage,
313324
responseHeaders,
314-
error);
325+
error,
326+
isVerbose);
315327
}
316328
}

src/main/java/com/microsoft/graph/requests/extensions/ChunkedUploadRequest.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public class ChunkedUploadRequest {
4545
private final BaseRequest baseRequest;
4646

4747
/**
48-
* The max retry for single request.
48+
* The max retry for a single request.
4949
*/
5050
private final int maxRetry;
5151

@@ -57,8 +57,8 @@ public class ChunkedUploadRequest {
5757
/**
5858
* Construct the ChunkedUploadRequest
5959
*
60-
* @param requestUrl The upload url.
61-
* @param client The OneDrive client.
60+
* @param requestUrl The upload URL.
61+
* @param client The Graph client.
6262
* @param options The query options.
6363
* @param chunk The chunk byte array.
6464
* @param chunkSize The chunk array size.
@@ -92,7 +92,7 @@ public ChunkedUploadRequest(final String requestUrl,
9292
/**
9393
* Upload a chunk with tries.
9494
*
95-
* @param responseHandler The handler handle http response.
95+
* @param responseHandler The handler to handle the HTTP response.
9696
* @param <UploadType> The upload item type.
9797
* @return The upload result.
9898
*/
@@ -102,7 +102,7 @@ public <UploadType> ChunkedUploadResult upload(
102102
try {
103103
Thread.sleep(RETRY_DELAY * this.retryCount * this.retryCount);
104104
} catch (final InterruptedException e) {
105-
this.baseRequest.getClient().getLogger().logError("Exception while waiting upload file retry", e);
105+
throw new ClientException("Exception while waiting to retry file upload.", e);
106106
}
107107

108108
ChunkedUploadResult result = null;
@@ -113,7 +113,7 @@ public <UploadType> ChunkedUploadResult upload(
113113
.getHttpProvider()
114114
.send(baseRequest, ChunkedUploadResult.class, this.data, responseHandler);
115115
} catch (final ClientException e) {
116-
this.baseRequest.getClient().getLogger().logDebug("Request failed with, retry if necessary.");
116+
throw new ClientException("Request failed with error, retry if necessary.", e);
117117
}
118118

119119
if (result != null && result.chunkCompleted()) {
@@ -124,7 +124,6 @@ public <UploadType> ChunkedUploadResult upload(
124124
}
125125

126126
return new ChunkedUploadResult(
127-
new ClientException("Upload session failed to many times.", null,
128-
GraphErrorCodes.UPLOAD_SESSION_INCOMPLETE));
127+
new ClientException("Upload session failed too many times.", null));
129128
}
130129
}

src/main/java/com/microsoft/graph/requests/extensions/ChunkedUploadResult.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public ChunkedUploadResult(ClientException error) {
6767
* @param exception The exception received from server.
6868
*/
6969
public ChunkedUploadResult(GraphServiceException exception) {
70-
this(new ClientException(exception.getMessage(/* verbose */ true), exception, GraphErrorCodes.UPLOAD_SESSION_FAILED));
70+
this(new ClientException(exception.getMessage(/* verbose */ true), exception));
7171
}
7272

7373
/**

src/main/java/com/microsoft/graph/requests/extensions/CustomRequestBuilder.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
import com.microsoft.graph.requests.extensions.GraphServiceClient;
99
import com.microsoft.graph.options.Option;
1010

11+
/**
12+
* The class for the CustomRequestBuilder
13+
*
14+
* @throws ClientException If the provided URL is malformed, the client exception will contain a MalformedURLException
15+
*/
1116
public class CustomRequestBuilder extends BaseRequestBuilder {
1217
public final Class responseType;
1318

src/test/java/com/microsoft/graph/concurrency/DefaultExecutorsTests.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import org.junit.Test;
88

99
import com.microsoft.graph.core.ClientException;
10-
import com.microsoft.graph.core.GraphErrorCodes;
1110
import com.microsoft.graph.logger.MockLogger;
1211

1312
import java.util.concurrent.atomic.AtomicBoolean;
@@ -95,14 +94,13 @@ public void testPerformOnForegroundWithClientException() {
9594
final String expectedLogMessage = "Starting foreground task, current active count:0, with exception com.microsoft.graph.core.ClientException: client exception message";
9695
final ExecutorTestCallback<String> callback = new ExecutorTestCallback<>();
9796

98-
defaultExecutors.performOnForeground(new ClientException(expectedExceptionMessage,null, GraphErrorCodes.INVALID_ACCEPT_TYPE),
97+
defaultExecutors.performOnForeground(new ClientException(expectedExceptionMessage,null),
9998
callback);
10099

101100
callback._completionWaiter.waitForSignal();
102101
assertFalse(callback._successCalled.get());
103102
assertTrue(callback._failureCalled.get());
104103
assertEquals(expectedExceptionMessage, callback._exceptionResult.get().getMessage());
105-
assertTrue(callback._exceptionResult.get().isError(GraphErrorCodes.INVALID_ACCEPT_TYPE));
106104
assertEquals(1,mLogger.getLogMessages().size());
107105
assertTrue(mLogger.hasMessage(expectedLogMessage));
108106
}

0 commit comments

Comments
 (0)