Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added stack trace to CosmosException, ResponseMessage.ErrorMessage includes full exception info. #1213

Merged
merged 27 commits into from
Feb 28, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d4b9c9c
Removed Error since it is not being used anywhere.
Feb 11, 2020
ef9a94b
Removed error since it's not being used
Feb 11, 2020
87b363c
Refactored added new exception types
Feb 13, 2020
d1406ec
ResponseMessage.ErrorMessage will now return the full CosmosException…
Feb 14, 2020
eb37121
Fixed build issue
Feb 14, 2020
e8422e3
Renamed exception to add Cosmos to avoid confusion with Document name…
Feb 18, 2020
f783e54
Fixed exception handling and updated tests.
Feb 19, 2020
61905b1
Fixed tests
Feb 20, 2020
23a7a99
Fixed ExceptionWithStackTraceException to use original exception stac…
Feb 20, 2020
73d5632
Merge remote-tracking branch 'origin/master' into users/jawilley/diag…
Feb 20, 2020
97fae63
Fixed merge conflicts with latest
Feb 20, 2020
968fb97
Added diagnostic context to exceptions.
Feb 20, 2020
1162ce1
Fixed test for retail build
Feb 20, 2020
32343f2
Updated error message field in linq tests
Feb 21, 2020
064c1f5
Converted the stack trace to a string. Removed creating the stack tra…
Feb 21, 2020
a41b615
Updated changelog
Feb 21, 2020
0d2e970
Removed typed exceptions to avoid exposing internal types.
Feb 25, 2020
b5507e0
Merged to latest
Feb 25, 2020
74beae5
Adding transport client exception tests.
Feb 26, 2020
300872b
Update Microsoft.Azure.Cosmos/src/Resource/CosmosExceptions/CosmosExc…
j82w Feb 27, 2020
fce942a
Update Microsoft.Azure.Cosmos/src/Resource/CosmosExceptions/CosmosExc…
j82w Feb 27, 2020
680cb2e
Removed diagnostics from Response.ErrorMessage
Feb 27, 2020
c4e9490
Fixed unit test
Feb 27, 2020
46d9b1c
Adding Error object to CosmosException for back compatability.
Feb 27, 2020
4a72093
Adding unit test for Error handling
Feb 27, 2020
cad13c7
Fixed DocumentServiceResponse handling
Feb 28, 2020
553a761
Increased EndpointFailureMockTest wait time to avoid transient failures.
Feb 28, 2020
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
2 changes: 1 addition & 1 deletion Microsoft.Azure.Cosmos/src/Handler/ResponseMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public virtual Stream Content
/// <summary>
/// Asserts if the current <see cref="HttpStatusCode"/> is a success.
/// </summary>
public virtual bool IsSuccessStatusCode => ((int)this.StatusCode >= 200) && ((int)this.StatusCode <= 299);
public virtual bool IsSuccessStatusCode => this.StatusCode.IsSuccess();

/// <summary>
/// Checks if the current <see cref="ResponseMessage"/> has a successful status code, otherwise, throws.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace Microsoft.Azure.Cosmos.Resource.CosmosExceptions
{
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using Microsoft.Azure.Documents;
Expand Down Expand Up @@ -113,6 +112,42 @@ internal static CosmosException Create(
responseMessage.CosmosException?.InnerException);
}

internal static CosmosException Create(
DocumentServiceResponse documentServiceResponse,
Headers responseHeaders,
RequestMessage requestMessage)
{
if (documentServiceResponse == null)
{
throw new ArgumentNullException(nameof(documentServiceResponse));
}

if (requestMessage == null)
{
throw new ArgumentNullException(nameof(requestMessage));
}

if (responseHeaders == null)
{
responseHeaders = documentServiceResponse.Headers.ToCosmosHeaders();
}

(Error error, string errorMessage) = CosmosExceptionFactory.GetErrorFromStream(documentServiceResponse.ResponseBody);

return CosmosExceptionFactory.Create(
statusCode: documentServiceResponse.StatusCode,
subStatusCode: (int)responseHeaders.SubStatusCode,
message: errorMessage,
stackTrace: null,
activityId: responseHeaders.ActivityId,
requestCharge: responseHeaders.RequestCharge,
retryAfter: responseHeaders.RetryAfter,
headers: responseHeaders,
diagnosticsContext: requestMessage.DiagnosticsContext,
error: error,
innerException: null);
}

internal static CosmosException Create(
StoreResponse storeResponse,
RequestMessage requestMessage)
Expand Down
68 changes: 46 additions & 22 deletions Microsoft.Azure.Cosmos/src/Util/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,43 +15,56 @@ namespace Microsoft.Azure.Cosmos
using Microsoft.Azure.Cosmos.Diagnostics;
using Microsoft.Azure.Cosmos.Resource.CosmosExceptions;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Collections;

internal static class Extensions
{
private static readonly char[] NewLineCharacters = new[] { '\r', '\n' };

internal static bool IsSuccess(this HttpStatusCode httpStatusCode)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Goodie

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just wonder if this will cause any issue when integrated internally, unless noone else created such an extension with that name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't since it's in the SDK namespace.

{
return ((int)httpStatusCode >= 200) && ((int)httpStatusCode <= 299);
}

internal static ResponseMessage ToCosmosResponseMessage(this DocumentServiceResponse documentServiceResponse, RequestMessage requestMessage)
{
Debug.Assert(requestMessage != null, nameof(requestMessage));

ResponseMessage responseMessage = new ResponseMessage(documentServiceResponse.StatusCode, requestMessage);
if (documentServiceResponse.ResponseBody != null)
{
responseMessage.Content = documentServiceResponse.ResponseBody;
}

if (documentServiceResponse.Headers != null)
{
foreach (string key in documentServiceResponse.Headers)
{
responseMessage.Headers.Add(key, documentServiceResponse.Headers[key]);
}
}

Headers headers = documentServiceResponse.Headers.ToCosmosHeaders();
CosmosClientSideRequestStatistics cosmosClientSideRequestStatistics = documentServiceResponse.RequestStats as CosmosClientSideRequestStatistics;
PointOperationStatistics pointOperationStatistics = new PointOperationStatistics(
activityId: responseMessage.Headers.ActivityId,
requestMessage.DiagnosticsContext.AddDiagnosticsInternal(new PointOperationStatistics(
activityId: headers.ActivityId,
statusCode: documentServiceResponse.StatusCode,
subStatusCode: documentServiceResponse.SubStatusCode,
requestCharge: responseMessage.Headers.RequestCharge,
errorMessage: responseMessage.ErrorMessage,
requestCharge: headers.RequestCharge,
errorMessage: null,
method: requestMessage?.Method,
requestUri: requestMessage?.RequestUri,
requestSessionToken: requestMessage?.Headers?.Session,
responseSessionToken: responseMessage.Headers.Session,
clientSideRequestStatistics: cosmosClientSideRequestStatistics);
responseSessionToken: headers.Session,
clientSideRequestStatistics: cosmosClientSideRequestStatistics));

// If it's considered a failure create the corresponding CosmosException
if (!documentServiceResponse.StatusCode.IsSuccess())
{
CosmosException cosmosException = CosmosExceptionFactory.Create(
documentServiceResponse,
headers,
requestMessage);

return cosmosException.ToCosmosResponseMessage(requestMessage);
}

ResponseMessage responseMessage = new ResponseMessage(
statusCode: documentServiceResponse.StatusCode,
requestMessage: requestMessage,
headers: headers,
cosmosException: null,
diagnostics: requestMessage.DiagnosticsContext)
{
Content = documentServiceResponse.ResponseBody
};

requestMessage.DiagnosticsContext.AddDiagnosticsInternal(pointOperationStatistics);
return responseMessage;
}

Expand Down Expand Up @@ -102,7 +115,7 @@ internal static ResponseMessage ToCosmosResponseMessage(this DocumentClientExcep
internal static ResponseMessage ToCosmosResponseMessage(this StoreResponse storeResponse, RequestMessage requestMessage)
{
// If it's considered a failure create the corresponding CosmosException
if (((int)storeResponse.StatusCode >= 200) && ((int)storeResponse.StatusCode <= 299))
if (!storeResponse.StatusCode.IsSuccess())
{
CosmosException cosmosException = CosmosExceptionFactory.Create(
storeResponse,
Expand Down Expand Up @@ -132,6 +145,17 @@ internal static Headers ToCosmosHeaders(this StoreResponse storeResponse)
return headers;
}

internal static Headers ToCosmosHeaders(this INameValueCollection nameValueCollection)
{
Headers headers = new Headers();
foreach (string key in nameValueCollection)
{
headers.Add(key, nameValueCollection[key]);
}

return headers;
}

internal static void TraceException(Exception exception)
{
AggregateException aggregateException = exception as AggregateException;
Expand Down