public CosmosOfferResult( HttpStatusCode statusCode, CosmosException cosmosRequestException) { this.StatusCode = statusCode; this.CosmosException = cosmosRequestException; }
public void ValidateExceptionStackTraceHandling() { CosmosException cosmosException = CosmosExceptionFactory.CreateNotFoundException("TestMessage"); Assert.AreEqual(null, cosmosException.StackTrace); Assert.IsFalse(cosmosException.ToString().Contains(nameof(ValidateExceptionStackTraceHandling))); try { throw cosmosException; } catch (CosmosException ce) { Assert.IsTrue(ce.StackTrace.Contains(nameof(ValidateExceptionStackTraceHandling)), ce.StackTrace); } string stackTrace = "OriginalDocumentClientExceptionStackTrace"; try { throw CosmosExceptionFactory.CreateNotFoundException("TestMessage", stackTrace: stackTrace); } catch (CosmosException ce) { Assert.AreEqual(stackTrace, ce.StackTrace); } }
internal CosmosException( HttpStatusCode statusCode, string message, int subStatusCode, string stackTrace, string activityId, double requestCharge, TimeSpan?retryAfter, Headers headers, ITrace trace, Error error, Exception innerException) : base(CosmosException.GetMessageHelper( statusCode, subStatusCode, message, activityId), innerException) { this.ResponseBody = message; this.stackTrace = stackTrace; this.ActivityId = activityId; this.StatusCode = statusCode; this.SubStatusCode = subStatusCode; this.RetryAfter = retryAfter; this.RequestCharge = requestCharge; this.Headers = headers; this.Error = error; this.Trace = trace; }
internal CosmosException( HttpStatusCode statusCodes, string message, int subStatusCode, string stackTrace, string activityId, double requestCharge, TimeSpan?retryAfter, Headers headers, CosmosDiagnosticsContext diagnosticsContext, Error error, Exception innerException) : base(CosmosException.GetMessageHelper( statusCodes, subStatusCode, message, activityId), innerException) { this.ResponseBody = message; this.stackTrace = stackTrace; this.ActivityId = activityId; this.StatusCode = statusCodes; this.SubStatusCode = subStatusCode; this.RetryAfter = retryAfter; this.RequestCharge = requestCharge; this.Headers = headers; this.Error = error; // Always have a diagnostic context. A new diagnostic will have useful info like user agent this.DiagnosticsContext = diagnosticsContext ?? new CosmosDiagnosticsContextCore(); }
private static string GetMessageHelper( HttpStatusCode statusCode, Headers headers, string responseBody, CosmosDiagnostics diagnostics) { StringBuilder stringBuilder = new StringBuilder(); CosmosException.AppendMessageWithoutDiagnostics( stringBuilder, statusCode, headers, responseBody); // Include the diagnostics for exceptions where it is critical // to root cause failures. if (statusCode == HttpStatusCode.RequestTimeout || statusCode == HttpStatusCode.InternalServerError || statusCode == HttpStatusCode.ServiceUnavailable || (statusCode == HttpStatusCode.NotFound && headers.SubStatusCode == SubStatusCodes.ReadSessionNotAvailable)) { stringBuilder.Append("; Diagnostics:"); stringBuilder.Append(diagnostics.ToString()); } return(stringBuilder.ToString()); }
public void EnsureCorrectStatusCode() { string testMessage = "Test" + Guid.NewGuid().ToString(); string activityId = Guid.NewGuid().ToString(); int substatuscode = 9000; string substatus = substatuscode.ToString(); double requestCharge = 42; double retryAfter = 9000; string retryAfterLiteral = retryAfter.ToString(); List <(HttpStatusCode statusCode, CosmosException exception)> exceptionsToStatusCodes = new List <(HttpStatusCode, CosmosException)>() { (HttpStatusCode.NotFound, CosmosExceptionFactory.CreateNotFoundException(testMessage, new Headers() { SubStatusCodeLiteral = substatus, ActivityId = activityId, RequestCharge = requestCharge, RetryAfterLiteral = retryAfterLiteral })), (HttpStatusCode.InternalServerError, CosmosExceptionFactory.CreateInternalServerErrorException(testMessage, new Headers() { SubStatusCodeLiteral = substatus, ActivityId = activityId, RequestCharge = requestCharge, RetryAfterLiteral = retryAfterLiteral })), (HttpStatusCode.BadRequest, CosmosExceptionFactory.CreateBadRequestException(testMessage, new Headers() { SubStatusCodeLiteral = substatus, ActivityId = activityId, RequestCharge = requestCharge, RetryAfterLiteral = retryAfterLiteral })), (HttpStatusCode.RequestTimeout, CosmosExceptionFactory.CreateRequestTimeoutException(testMessage, new Headers() { SubStatusCodeLiteral = substatus, ActivityId = activityId, RequestCharge = requestCharge, RetryAfterLiteral = retryAfterLiteral })), ((HttpStatusCode)429, CosmosExceptionFactory.CreateThrottledException(testMessage, new Headers() { SubStatusCodeLiteral = substatus, ActivityId = activityId, RequestCharge = requestCharge, RetryAfterLiteral = retryAfterLiteral })), }; foreach ((HttpStatusCode statusCode, CosmosException exception) in exceptionsToStatusCodes) { this.ValidateExceptionInfo( exception, statusCode, substatus, testMessage, activityId, requestCharge, retryAfter); } CosmosException cosmosException = CosmosExceptionFactory.CreateNotFoundException(testMessage, new Headers() { SubStatusCodeLiteral = ((int)SubStatusCodes.ReadSessionNotAvailable).ToString(), ActivityId = activityId, RequestCharge = requestCharge, RetryAfterLiteral = retryAfterLiteral }); this.ValidateExceptionInfo( cosmosException, HttpStatusCode.NotFound, ((int)SubStatusCodes.ReadSessionNotAvailable).ToString(), testMessage, activityId, requestCharge, retryAfter); }
/// <summary> /// RecordOtelAttributes /// </summary> /// <param name="exception"></param> /// <param name="scope"></param> internal static void RecordOtelAttributes(CosmosException exception, DiagnosticScope scope) { scope.AddAttribute(OpenTelemetryAttributeKeys.StatusCode, exception.StatusCode); scope.AddAttribute(OpenTelemetryAttributeKeys.RequestCharge, exception.RequestCharge); scope.AddAttribute(OpenTelemetryAttributeKeys.Region, ClientTelemetryHelper.GetContactedRegions(exception.Diagnostics)); scope.AddAttribute(OpenTelemetryAttributeKeys.RequestDiagnostics, exception.Diagnostics); scope.AddAttribute(OpenTelemetryAttributeKeys.ExceptionMessage, exception.Message); }
private void ValidateExceptionInfo( CosmosException exception, HttpStatusCode httpStatusCode, string message) { Assert.AreEqual(httpStatusCode, exception.StatusCode); Assert.IsTrue(exception.ToString().Contains(message)); }
internal async Task <ThroughputResponse> ReplaceThroughputPropertiesIfExistsAsync( string targetRID, ThroughputProperties throughputProperties, RequestOptions requestOptions, CancellationToken cancellationToken = default) { try { (ThroughputProperties currentProperty, double requestCharge) = await this.GetOfferV2Async <ThroughputProperties>(targetRID, failIfNotConfigured : false, cancellationToken : cancellationToken); if (currentProperty == null) { CosmosException notFound = CosmosExceptionFactory.CreateNotFoundException( $"Throughput is not configured for {targetRID}", headers: new Headers() { RequestCharge = requestCharge }); return(new ThroughputResponse( httpStatusCode: notFound.StatusCode, headers: notFound.Headers, throughputProperties: null, diagnostics: notFound.Diagnostics, requestMessage: null)); } currentProperty.Content = throughputProperties.Content; return(await this.GetThroughputResponseAsync( streamPayload : this.ClientContext.SerializerCore.ToStream(currentProperty), operationType : OperationType.Replace, linkUri : new Uri(currentProperty.SelfLink, UriKind.Relative), resourceType : ResourceType.Offer, currentRequestCharge : requestCharge, requestOptions : requestOptions, cancellationToken : cancellationToken)); } catch (DocumentClientException dce) { ResponseMessage responseMessage = dce.ToCosmosResponseMessage(null); return(new ThroughputResponse( responseMessage.StatusCode, headers: responseMessage.Headers, throughputProperties: null, diagnostics: responseMessage.Diagnostics, requestMessage: responseMessage.RequestMessage)); } catch (AggregateException ex) { ResponseMessage responseMessage = TransportHandler.AggregateExceptionConverter(ex, null); return(new ThroughputResponse( responseMessage.StatusCode, headers: responseMessage.Headers, throughputProperties: null, diagnostics: responseMessage.Diagnostics, requestMessage: responseMessage.RequestMessage)); } }
public void VerifyDiagnosticsInTimeoutAndServerError() { ITrace trace = NoOpTrace.Singleton; string diagnosticString = new Diagnostics.CosmosTraceDiagnostics(trace).ToString(); CosmosException cosmosException = new CosmosException( statusCode: HttpStatusCode.RequestTimeout, message: "Test", stackTrace: null, headers: null, trace: trace, error: null, innerException: null); Assert.IsTrue(cosmosException.Message.EndsWith(diagnosticString)); Assert.IsTrue(cosmosException.ToString().Contains(diagnosticString)); cosmosException = new CosmosException( statusCode: HttpStatusCode.InternalServerError, message: "Test", stackTrace: null, headers: null, trace: trace, error: null, innerException: null); Assert.IsTrue(cosmosException.Message.EndsWith(diagnosticString)); Assert.IsTrue(cosmosException.ToString().Contains(diagnosticString)); cosmosException = new CosmosException( statusCode: HttpStatusCode.ServiceUnavailable, message: "Test", stackTrace: null, headers: null, trace: trace, error: null, innerException: null); Assert.IsTrue(cosmosException.Message.EndsWith(diagnosticString)); Assert.IsTrue(cosmosException.ToString().Contains(diagnosticString)); cosmosException = new CosmosException( statusCode: HttpStatusCode.NotFound, message: "Test", stackTrace: null, headers: null, trace: trace, error: null, innerException: null); Assert.IsFalse(cosmosException.Message.Contains(diagnosticString)); Assert.IsTrue(cosmosException.ToString().Contains(diagnosticString)); }
private void ValidateExceptionInfo( CosmosException exception, HttpStatusCode httpStatusCode, string message) { Assert.AreEqual(message, exception.ResponseBody); Assert.AreEqual(httpStatusCode, exception.StatusCode); Assert.IsTrue(exception.ToString().Contains(message)); string expectedMessage = $"Response status code does not indicate success: {httpStatusCode} ({(int)httpStatusCode}); Substatus: 0; ActivityId: {exception.ActivityId}; Reason: ({message});"; Assert.AreEqual(expectedMessage, exception.Message); }
internal static ResponseMessage ToCosmosResponseMessage(this DocumentClientException documentClientException, RequestMessage requestMessage) { CosmosDiagnosticsContext diagnosticsContext = requestMessage?.DiagnosticsContext; if (requestMessage != null) { diagnosticsContext = requestMessage.DiagnosticsContext; if (diagnosticsContext == null) { throw new ArgumentNullException("Request message should contain a DiagnosticsContext"); } } else { diagnosticsContext = new CosmosDiagnosticsContextCore(); } CosmosException cosmosException = CosmosExceptionFactory.Create( documentClientException, diagnosticsContext); PointOperationStatistics pointOperationStatistics = new PointOperationStatistics( activityId: cosmosException.Headers.ActivityId, statusCode: cosmosException.StatusCode, subStatusCode: (int)SubStatusCodes.Unknown, responseTimeUtc: DateTime.UtcNow, requestCharge: cosmosException.Headers.RequestCharge, errorMessage: documentClientException.ToString(), method: requestMessage?.Method, requestUri: requestMessage?.RequestUriString, requestSessionToken: requestMessage?.Headers?.Session, responseSessionToken: cosmosException.Headers.Session); diagnosticsContext.AddDiagnosticsInternal(pointOperationStatistics); // if StatusCode is null it is a client business logic error and it never hit the backend, so throw if (documentClientException.StatusCode == null) { throw cosmosException; } // if there is a status code then it came from the backend, return error as http error instead of throwing the exception ResponseMessage responseMessage = cosmosException.ToCosmosResponseMessage(requestMessage); if (requestMessage != null) { requestMessage.Properties.Remove(nameof(DocumentClientException)); requestMessage.Properties.Add(nameof(DocumentClientException), documentClientException); } return(responseMessage); }
private void ValidateExceptionInfo( CosmosException exception, HttpStatusCode httpStatusCode, string substatus, string message, string activityId, double requestCharge, double retryAfter) { Assert.AreEqual(message, exception.ResponseBody); Assert.AreEqual(httpStatusCode, exception.StatusCode); Assert.AreEqual(int.Parse(substatus), exception.SubStatusCode); Assert.AreEqual(substatus, exception.Headers.SubStatusCodeLiteral); Assert.AreEqual(activityId, exception.ActivityId); Assert.AreEqual(activityId, exception.Headers.ActivityId); Assert.AreEqual(requestCharge, exception.RequestCharge); Assert.AreEqual(requestCharge, exception.Headers.RequestCharge); Assert.AreEqual(TimeSpan.FromMilliseconds(retryAfter), exception.RetryAfter); Assert.AreEqual(TimeSpan.FromMilliseconds(retryAfter), exception.Headers.RetryAfter); Assert.IsTrue(exception.ToString().Contains(message)); string expectedMessage = $"Response status code does not indicate success: {httpStatusCode} ({(int)httpStatusCode}); Substatus: {substatus}; ActivityId: {exception.ActivityId}; Reason: ({message});"; if (httpStatusCode == HttpStatusCode.RequestTimeout || httpStatusCode == HttpStatusCode.InternalServerError || httpStatusCode == HttpStatusCode.ServiceUnavailable || (httpStatusCode == HttpStatusCode.NotFound && exception.Headers.SubStatusCode == SubStatusCodes.ReadSessionNotAvailable)) { expectedMessage += "; Diagnostics:" + new Diagnostics.CosmosTraceDiagnostics(NoOpTrace.Singleton).ToString(); } Assert.AreEqual(expectedMessage, exception.Message); // Verify updating the header updates the exception info exception.Headers.SubStatusCodeLiteral = "1234"; Assert.AreEqual(1234, exception.SubStatusCode); Assert.AreEqual("1234", exception.Headers.SubStatusCodeLiteral); activityId = Guid.NewGuid().ToString(); exception.Headers.ActivityId = activityId; Assert.AreEqual(activityId, exception.ActivityId); Assert.AreEqual(activityId, exception.Headers.ActivityId); requestCharge = 4321.09; exception.Headers.RequestCharge = requestCharge; Assert.AreEqual(requestCharge, exception.RequestCharge); Assert.AreEqual(requestCharge, exception.Headers.RequestCharge); retryAfter = 98754; exception.Headers.RetryAfterLiteral = retryAfter.ToString(); Assert.AreEqual(TimeSpan.FromMilliseconds(retryAfter), exception.RetryAfter); Assert.AreEqual(TimeSpan.FromMilliseconds(retryAfter), exception.Headers.RetryAfter); }
public void VerifyHeaderAlwaysExists() { CosmosException cosmosException = new CosmosException( statusCode: HttpStatusCode.BadRequest, message: "Test", stackTrace: null, headers: null, trace: NoOpTrace.Singleton, error: null, innerException: null); Assert.IsNotNull(cosmosException.Headers, "Header should always be created to avoid null refs caused by users always expecting it to be there"); }
/// <summary> /// Create a <see cref="ResponseMessage"/> /// </summary> /// <param name="statusCode">The HttpStatusCode of the response</param> /// <param name="requestMessage">The <see cref="Cosmos.RequestMessage"/> object</param> /// <param name="headers">The headers for the response.</param> /// <param name="cosmosException">The exception if the response is from an error.</param> /// <param name="diagnostics">The diagnostics for the request</param> internal ResponseMessage( HttpStatusCode statusCode, RequestMessage requestMessage, Headers headers, CosmosException cosmosException, CosmosDiagnosticsContext diagnostics) { this.StatusCode = statusCode; this.RequestMessage = requestMessage; this.CosmosException = cosmosException; this.Headers = headers ?? new Headers(); this.DiagnosticsContext = diagnostics ?? throw new ArgumentNullException(nameof(diagnostics)); }
internal static ResponseMessage ToCosmosResponseMessage(this DocumentServiceResponse documentServiceResponse, RequestMessage requestMessage) { Debug.Assert(requestMessage != null, nameof(requestMessage)); Headers headers = documentServiceResponse.Headers.ToCosmosHeaders(); // Only record point operation stats if ClientSideRequestStats did not record the response. CosmosClientSideRequestStatistics clientSideRequestStatistics = documentServiceResponse.RequestStats as CosmosClientSideRequestStatistics; if (clientSideRequestStatistics == null || (clientSideRequestStatistics.ContactedReplicas.Count == 0 && clientSideRequestStatistics.FailedReplicas.Count == 0)) { requestMessage.DiagnosticsContext.AddDiagnosticsInternal(new PointOperationStatistics( activityId: headers.ActivityId, responseTimeUtc: DateTime.UtcNow, statusCode: documentServiceResponse.StatusCode, subStatusCode: documentServiceResponse.SubStatusCode, requestCharge: headers.RequestCharge, errorMessage: null, method: requestMessage?.Method, requestUri: requestMessage?.RequestUri, requestSessionToken: requestMessage?.Headers?.Session, responseSessionToken: headers.Session)); } // 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 }; return(responseMessage); }
private void ValidateExceptionInfo( CosmosException exception, HttpStatusCode httpStatusCode, string substatus, string message, string activityId, double requestCharge, double retryAfter) { Assert.AreEqual(message, exception.ResponseBody); Assert.AreEqual(httpStatusCode, exception.StatusCode); Assert.AreEqual(int.Parse(substatus), exception.SubStatusCode); Assert.AreEqual(substatus, exception.Headers.SubStatusCodeLiteral); Assert.AreEqual(activityId, exception.ActivityId); Assert.AreEqual(activityId, exception.Headers.ActivityId); Assert.AreEqual(requestCharge, exception.RequestCharge); Assert.AreEqual(requestCharge, exception.Headers.RequestCharge); Assert.AreEqual(TimeSpan.FromMilliseconds(retryAfter), exception.RetryAfter); Assert.AreEqual(TimeSpan.FromMilliseconds(retryAfter), exception.Headers.RetryAfter); Assert.IsTrue(exception.ToString().Contains(message)); string expectedMessage = $"Response status code does not indicate success: {httpStatusCode} ({(int)httpStatusCode}); Substatus: {substatus}; ActivityId: {exception.ActivityId}; Reason: ({message});"; Assert.AreEqual(expectedMessage, exception.Message); // Verify updating the header updates the exception info exception.Headers.SubStatusCodeLiteral = "1234"; Assert.AreEqual(1234, exception.SubStatusCode); Assert.AreEqual("1234", exception.Headers.SubStatusCodeLiteral); activityId = Guid.NewGuid().ToString(); exception.Headers.ActivityId = activityId; Assert.AreEqual(activityId, exception.ActivityId); Assert.AreEqual(activityId, exception.Headers.ActivityId); requestCharge = 4321.09; exception.Headers.RequestCharge = requestCharge; Assert.AreEqual(requestCharge, exception.RequestCharge); Assert.AreEqual(requestCharge, exception.Headers.RequestCharge); retryAfter = 98754; exception.Headers.RetryAfterLiteral = retryAfter.ToString(); Assert.AreEqual(TimeSpan.FromMilliseconds(retryAfter), exception.RetryAfter); Assert.AreEqual(TimeSpan.FromMilliseconds(retryAfter), exception.Headers.RetryAfter); }
/// <summary> /// Get the next set of results from the cosmos service /// </summary> /// <param name="cancellationToken">(Optional) <see cref="CancellationToken"/> representing request cancellation.</param> /// <returns>A query response from cosmos service</returns> public override async Task <ResponseMessage> ReadNextAsync(CancellationToken cancellationToken = default(CancellationToken)) { CosmosDiagnosticsContext diagnostics = CosmosDiagnosticsContext.Create(this.changeFeedOptions); using (diagnostics.GetOverallScope()) { diagnostics.AddDiagnosticsInternal(new FeedRangeStatistics(this.FeedRangeInternal)); if (!this.lazyContainerRid.ValueInitialized) { using (diagnostics.CreateScope("InitializeContainerResourceId")) { TryCatch <string> tryInitializeContainerRId = await this.lazyContainerRid.GetValueAsync(cancellationToken); if (!tryInitializeContainerRId.Succeeded) { CosmosException cosmosException = tryInitializeContainerRId.Exception.InnerException as CosmosException; return(cosmosException.ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnostics))); } } using (diagnostics.CreateScope("InitializeContinuation")) { if (this.FeedRangeContinuation != null) { TryCatch validateContainer = this.FeedRangeContinuation.ValidateContainer(this.lazyContainerRid.Result.Result); if (!validateContainer.Succeeded) { return(CosmosExceptionFactory.CreateBadRequestException( message: validateContainer.Exception.InnerException.Message, innerException: validateContainer.Exception.InnerException, diagnosticsContext: diagnostics).ToCosmosResponseMessage(new RequestMessage(method: null, requestUri: null, diagnosticsContext: diagnostics))); } } else { await this.InitializeFeedContinuationAsync(cancellationToken); } } } return(await this.ReadNextInternalAsync(diagnostics, cancellationToken)); } }
/// <summary> /// Create a <see cref="ResponseMessage"/> /// </summary> /// <param name="statusCode">The HttpStatusCode of the response</param> /// <param name="requestMessage">The <see cref="Cosmos.RequestMessage"/> object</param> /// <param name="headers">The headers for the response.</param> /// <param name="cosmosException">The exception if the response is from an error.</param> /// <param name="trace">The trace for the request</param> internal ResponseMessage( HttpStatusCode statusCode, RequestMessage requestMessage, Headers headers, CosmosException cosmosException, ITrace trace) { this.StatusCode = statusCode; this.RequestMessage = requestMessage; this.CosmosException = cosmosException; this.Headers = headers ?? new Headers(); if (requestMessage != null && requestMessage.Trace != null) { this.Trace = requestMessage.Trace; } else { this.Trace = trace ?? throw new ArgumentNullException(nameof(trace)); } }
internal CosmosException( HttpStatusCode statusCode, string message, string stackTrace, Headers headers, ITrace trace, Error error, Exception innerException) : base(CosmosException.GetMessageHelper( statusCode, headers, message), innerException) { this.ResponseBody = message; this.stackTrace = stackTrace; this.StatusCode = statusCode; this.Headers = headers ?? new Headers(); this.Error = error; this.Trace = trace; }
internal static QueryResponse CreateFailure( CosmosQueryResponseMessageHeaders responseHeaders, HttpStatusCode statusCode, RequestMessage requestMessage, CosmosException cosmosException, CosmosDiagnosticsContext diagnostics) { QueryResponse cosmosQueryResponse = new QueryResponse( result: new List <CosmosElement>(), count: 0, responseLengthBytes: 0, responseHeaders: responseHeaders, diagnostics: diagnostics, statusCode: statusCode, cosmosException: cosmosException, requestMessage: requestMessage, memoryStream: null, serializationOptions: null); return(cosmosQueryResponse); }
private string ToStringHelper( StringBuilder stringBuilder) { if (stringBuilder == null) { throw new ArgumentNullException(nameof(stringBuilder)); } CosmosException.AppendMessageWithoutDiagnostics( stringBuilder, this.StatusCode, this.Headers, this.ResponseBody); stringBuilder.AppendLine(); if (this.InnerException != null) { stringBuilder.Append(" ---> "); stringBuilder.Append(this.InnerException); stringBuilder.AppendLine(); stringBuilder.Append(" "); stringBuilder.Append("--- End of inner exception stack trace ---"); stringBuilder.AppendLine(); } if (this.StackTrace != null) { stringBuilder.Append(this.StackTrace); stringBuilder.AppendLine(); } if (this.Diagnostics != null) { stringBuilder.Append("--- Cosmos Diagnostics ---"); stringBuilder.Append(this.Diagnostics); } return(stringBuilder.ToString()); }
public void ValidateErrorHandling() { Error error = new Error() { Code = System.Net.HttpStatusCode.BadRequest.ToString(), Message = "Unsupported Query", AdditionalErrorInfo = "Additional error info message", }; CosmosDiagnosticsContext diagnostics = new CosmosDiagnosticsContextCore(); CosmosException cosmosException = CosmosExceptionFactory.CreateBadRequestException( error.ToString(), error: error, diagnosticsContext: diagnostics); ResponseMessage responseMessage = QueryResponse.CreateFailure( statusCode: System.Net.HttpStatusCode.BadRequest, cosmosException: cosmosException, requestMessage: null, diagnostics: diagnostics, responseHeaders: null); Assert.AreEqual(error, responseMessage.CosmosException.Error); Assert.IsTrue(responseMessage.ErrorMessage.Contains(error.Message)); Assert.IsTrue(responseMessage.ErrorMessage.Contains(error.AdditionalErrorInfo)); try { responseMessage.EnsureSuccessStatusCode(); Assert.Fail("Should throw exception"); } catch (CosmosException ce) when(ce.StatusCode == HttpStatusCode.BadRequest) { Assert.IsTrue(ce.Message.Contains(error.Message)); Assert.IsTrue(ce.ToString().Contains(error.Message)); Assert.IsTrue(ce.ToString().Contains(error.AdditionalErrorInfo)); } }
internal static ResponseMessage ToCosmosResponseMessage(this StoreResponse storeResponse, RequestMessage requestMessage) { // If it's considered a failure create the corresponding CosmosException if (!storeResponse.StatusCode.IsSuccess()) { CosmosException cosmosException = CosmosExceptionFactory.Create( storeResponse, requestMessage); return(cosmosException.ToCosmosResponseMessage(requestMessage)); } // Is status code conversion lossy? ResponseMessage responseMessage = new ResponseMessage((HttpStatusCode)storeResponse.Status, requestMessage); if (storeResponse.ResponseBody != null) { responseMessage.Content = storeResponse.ResponseBody; } return(responseMessage); }
private QueryResponse( IReadOnlyList <CosmosElement> result, int count, long responseLengthBytes, CosmosQueryResponseMessageHeaders responseHeaders, HttpStatusCode statusCode, RequestMessage requestMessage, CosmosDiagnosticsContext diagnostics, CosmosException cosmosException, Lazy <MemoryStream> memoryStream, CosmosSerializationFormatOptions serializationOptions) : base( statusCode: statusCode, requestMessage: requestMessage, cosmosException: cosmosException, headers: responseHeaders, diagnostics: diagnostics) { this.CosmosElements = result; this.Count = count; this.ResponseLengthBytes = responseLengthBytes; this.memoryStream = memoryStream; this.CosmosSerializationOptions = serializationOptions; }
public void VerifyNullHeaderLogic() { string testMessage = "Test" + Guid.NewGuid().ToString(); CosmosException exception = new CosmosException( statusCode: HttpStatusCode.BadRequest, message: testMessage, stackTrace: null, headers: null, trace: NoOpTrace.Singleton, error: null, innerException: null); Assert.IsNotNull(exception.Headers, "Header should always be created to avoid null refs caused by users always expecting it to be there"); Assert.AreEqual(HttpStatusCode.BadRequest, exception.StatusCode); Assert.IsTrue(exception.ToString().Contains(testMessage)); exception = new CosmosException( statusCode: HttpStatusCode.BadRequest, message: testMessage, subStatusCode: 42, activityId: "test", requestCharge: 4); Assert.IsNotNull(exception.Headers, "Header should always be created to avoid null refs caused by users always expecting it to be there"); Assert.AreEqual(HttpStatusCode.BadRequest, exception.StatusCode); Assert.AreEqual(testMessage, exception.ResponseBody); Assert.AreEqual(HttpStatusCode.BadRequest, exception.StatusCode); Assert.AreEqual(42, exception.SubStatusCode); Assert.AreEqual("42", exception.Headers.SubStatusCodeLiteral); Assert.AreEqual("test", exception.ActivityId); Assert.AreEqual("test", exception.Headers.ActivityId); Assert.AreEqual(4, exception.RequestCharge); Assert.AreEqual(4, exception.Headers.RequestCharge); Assert.IsTrue(exception.ToString().Contains(testMessage)); }
internal CosmosException( HttpStatusCode statusCode, string message, string stackTrace, Headers headers, ITrace trace, Error error, Exception innerException) // The message is overridden. Base exception does not have CTOR for just innerException and the property is not virtual : base(string.Empty, innerException) { this.ResponseBody = message; this.stackTrace = stackTrace; this.StatusCode = statusCode; this.Headers = headers ?? new Headers(); this.Error = error; this.Trace = trace; this.Diagnostics = new CosmosTraceDiagnostics(this.Trace ?? NoOpTrace.Singleton); this.lazyMessage = new Lazy <string>(() => CosmosException.GetMessageHelper( statusCode, this.Headers, this.ResponseBody, this.Diagnostics)); }
/// <summary> /// Get the next set of results from the cosmos service /// </summary> /// <param name="cancellationToken">(Optional) <see cref="CancellationToken"/> representing request cancellation.</param> /// <returns>A query response from cosmos service</returns> public override async Task <ResponseMessage> ReadNextAsync(CancellationToken cancellationToken = default) { cancellationToken.ThrowIfCancellationRequested(); if (!this.hasMoreResults) { throw new InvalidOperationException("Should not be calling FeedIterator that does not have any more results"); } if (this.monadicEnumerator.Failed) { this.hasMoreResults = false; CosmosException cosmosException = ExceptionToCosmosException.CreateFromException(this.monadicEnumerator.Exception); return(new ResponseMessage( statusCode: System.Net.HttpStatusCode.BadRequest, requestMessage: null, headers: cosmosException.Headers, cosmosException: cosmosException, diagnostics: cosmosException.DiagnosticsContext)); } CrossPartitionReadFeedAsyncEnumerator enumerator = this.monadicEnumerator.Result; TryCatch <ReadFeedPage> monadicPage; try { if (!await enumerator.MoveNextAsync()) { throw new InvalidOperationException("Should not be calling enumerator that does not have any more results"); } monadicPage = enumerator.Current; } catch (Exception ex) { monadicPage = TryCatch <ReadFeedPage> .FromException(ex); } if (monadicPage.Failed) { CosmosException cosmosException = ExceptionToCosmosException.CreateFromException(monadicPage.Exception); if (!IsRetriableException(cosmosException)) { this.hasMoreResults = false; } return(new ResponseMessage( statusCode: cosmosException.StatusCode, requestMessage: null, headers: cosmosException.Headers, cosmosException: cosmosException, diagnostics: cosmosException.DiagnosticsContext)); } ReadFeedPage readFeedPage = monadicPage.Result; if (readFeedPage.State == default) { this.hasMoreResults = false; } // Make the continuation token match the older format: string continuationToken; if (readFeedPage.State != null) { List <CompositeContinuationToken> compositeContinuationTokens = new List <CompositeContinuationToken>(); CosmosArray compositeContinuationTokensCosmosArray = (CosmosArray)readFeedPage.State.ContinuationToken; foreach (CosmosElement arrayItem in compositeContinuationTokensCosmosArray) { ReadFeedContinuationToken readFeedContinuationToken = ReadFeedContinuationToken.MonadicConvertFromCosmosElement(arrayItem).Result; FeedRangeEpk feedRangeEpk = (FeedRangeEpk)readFeedContinuationToken.Range; ReadFeedState readFeedState = readFeedContinuationToken.State; CompositeContinuationToken compositeContinuationToken = new CompositeContinuationToken() { Range = feedRangeEpk.Range, Token = readFeedState.ContinuationToken.ToString(), }; compositeContinuationTokens.Add(compositeContinuationToken); } FeedRangeCompositeContinuation feedRangeCompositeContinuation = new FeedRangeCompositeContinuation( containerRid: string.Empty, feedRange: FeedRangeEpk.FullRange, compositeContinuationTokens); continuationToken = feedRangeCompositeContinuation.ToString(); } else { continuationToken = null; } return(new ResponseMessage( statusCode: System.Net.HttpStatusCode.OK, requestMessage: default,
private static TryCatch <QueryPage> GetCosmosElementResponse( Guid clientQueryCorrelationId, QueryRequestOptions requestOptions, ResourceType resourceType, ResponseMessage cosmosResponseMessage, PartitionKeyRangeIdentity partitionKeyRangeIdentity, Action <QueryPageDiagnostics> queryPageDiagnostics, ITrace trace) { using (ITrace getCosmosElementResponse = trace.StartChild("Get Cosmos Element Response", TraceComponent.Json, Tracing.TraceLevel.Info)) { using (cosmosResponseMessage) { QueryPageDiagnostics queryPage = new QueryPageDiagnostics( clientQueryCorrelationId: clientQueryCorrelationId, partitionKeyRangeId: partitionKeyRangeIdentity.PartitionKeyRangeId, queryMetricText: cosmosResponseMessage.Headers.QueryMetricsText, indexUtilizationText: cosmosResponseMessage.Headers[HttpConstants.HttpHeaders.IndexUtilization], diagnosticsContext: cosmosResponseMessage.DiagnosticsContext); queryPageDiagnostics(queryPage); if ( cosmosResponseMessage.Headers.QueryMetricsText != null && BackendMetricsParser.TryParse(cosmosResponseMessage.Headers.QueryMetricsText, out BackendMetrics backendMetrics)) { QueryMetricsTraceDatum datum = new QueryMetricsTraceDatum( new QueryMetrics(backendMetrics, IndexUtilizationInfo.Empty, ClientSideMetrics.Empty)); trace.AddDatum("Query Metrics", datum); } if (!cosmosResponseMessage.IsSuccessStatusCode) { CosmosException exception; if (cosmosResponseMessage.CosmosException != null) { exception = cosmosResponseMessage.CosmosException; } else { exception = new CosmosException( cosmosResponseMessage.ErrorMessage, cosmosResponseMessage.StatusCode, (int)cosmosResponseMessage.Headers.SubStatusCode, cosmosResponseMessage.Headers.ActivityId, cosmosResponseMessage.Headers.RequestCharge); } return(TryCatch <QueryPage> .FromException(exception)); } if (!(cosmosResponseMessage.Content is MemoryStream memoryStream)) { memoryStream = new MemoryStream(); cosmosResponseMessage.Content.CopyTo(memoryStream); } long responseLengthBytes = memoryStream.Length; CosmosArray documents = CosmosQueryClientCore.ParseElementsFromRestStream( memoryStream, resourceType, requestOptions.CosmosSerializationFormatOptions); CosmosQueryExecutionInfo cosmosQueryExecutionInfo; if (cosmosResponseMessage.Headers.TryGetValue(QueryExecutionInfoHeader, out string queryExecutionInfoString)) { cosmosQueryExecutionInfo = JsonConvert.DeserializeObject <CosmosQueryExecutionInfo>(queryExecutionInfoString); } else { cosmosQueryExecutionInfo = default; } QueryState queryState; if (cosmosResponseMessage.Headers.ContinuationToken != null) { queryState = new QueryState(CosmosString.Create(cosmosResponseMessage.Headers.ContinuationToken)); } else { queryState = default; } QueryPage response = new QueryPage( documents, cosmosResponseMessage.Headers.RequestCharge, cosmosResponseMessage.Headers.ActivityId, responseLengthBytes, cosmosQueryExecutionInfo, disallowContinuationTokenMessage: null, queryState); return(TryCatch <QueryPage> .FromResult(response)); } } }
private static TryCatch <QueryPage> GetCosmosElementResponse( QueryRequestOptions requestOptions, ResourceType resourceType, ResponseMessage cosmosResponseMessage, ITrace trace) { using (ITrace getCosmosElementResponse = trace.StartChild("Get Cosmos Element Response", TraceComponent.Json, Tracing.TraceLevel.Info)) { using (cosmosResponseMessage) { if ( cosmosResponseMessage.Headers.QueryMetricsText != null && BackendMetricsParser.TryParse(cosmosResponseMessage.Headers.QueryMetricsText, out BackendMetrics backendMetrics)) { QueryMetricsTraceDatum datum = new QueryMetricsTraceDatum( new QueryMetrics(backendMetrics, IndexUtilizationInfo.Empty, ClientSideMetrics.Empty)); trace.AddDatum("Query Metrics", datum); } if (!cosmosResponseMessage.IsSuccessStatusCode) { CosmosException exception = cosmosResponseMessage.CosmosException ?? new CosmosException( cosmosResponseMessage.ErrorMessage, cosmosResponseMessage.StatusCode, (int)cosmosResponseMessage.Headers.SubStatusCode, cosmosResponseMessage.Headers.ActivityId, cosmosResponseMessage.Headers.RequestCharge); return(TryCatch <QueryPage> .FromException(exception)); } if (!(cosmosResponseMessage.Content is MemoryStream memoryStream)) { memoryStream = new MemoryStream(); cosmosResponseMessage.Content.CopyTo(memoryStream); } long responseLengthBytes = memoryStream.Length; CosmosArray documents = CosmosQueryClientCore.ParseElementsFromRestStream( memoryStream, resourceType, requestOptions.CosmosSerializationFormatOptions); CosmosQueryExecutionInfo cosmosQueryExecutionInfo; if (cosmosResponseMessage.Headers.TryGetValue(QueryExecutionInfoHeader, out string queryExecutionInfoString)) { cosmosQueryExecutionInfo = JsonConvert.DeserializeObject <CosmosQueryExecutionInfo>(queryExecutionInfoString); } else { cosmosQueryExecutionInfo = default; } QueryState queryState; if (cosmosResponseMessage.Headers.ContinuationToken != null) { queryState = new QueryState(CosmosString.Create(cosmosResponseMessage.Headers.ContinuationToken)); } else { queryState = default; } Dictionary <string, string> additionalHeaders = new Dictionary <string, string>(); foreach (string key in cosmosResponseMessage.Headers) { if (!QueryPage.BannedHeaders.Contains(key)) { additionalHeaders[key] = cosmosResponseMessage.Headers[key]; } } QueryPage response = new QueryPage( documents, cosmosResponseMessage.Headers.RequestCharge, cosmosResponseMessage.Headers.ActivityId, responseLengthBytes, cosmosQueryExecutionInfo, disallowContinuationTokenMessage: null, additionalHeaders, queryState); return(TryCatch <QueryPage> .FromResult(response)); } } }