diff --git a/Microsoft.Azure.Cosmos/src/Handler/ResponseMessage.cs b/Microsoft.Azure.Cosmos/src/Handler/ResponseMessage.cs index eca571d01c..19c204b799 100644 --- a/Microsoft.Azure.Cosmos/src/Handler/ResponseMessage.cs +++ b/Microsoft.Azure.Cosmos/src/Handler/ResponseMessage.cs @@ -100,7 +100,7 @@ public virtual Stream Content /// /// Gets the reason for a failure in the current response. /// - public virtual string ErrorMessage => this.CosmosException?.ToString(); + public virtual string ErrorMessage => this.CosmosException?.Message; /// /// Gets the current HTTP headers. diff --git a/Microsoft.Azure.Cosmos/src/Resource/CosmosExceptions/CosmosException.cs b/Microsoft.Azure.Cosmos/src/Resource/CosmosExceptions/CosmosException.cs index 2e36a5e14d..e8a940fb39 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/CosmosExceptions/CosmosException.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/CosmosExceptions/CosmosException.cs @@ -28,7 +28,11 @@ internal CosmosException( CosmosDiagnosticsContext diagnosticsContext, Error error, Exception innerException) - : base(message, innerException) + : base(CosmosException.GetMessageHelper( + statusCodes, + subStatusCode, + message, + activityId), innerException) { this.ResponseBody = message; this.stackTrace = stackTrace; @@ -69,9 +73,6 @@ public CosmosException( this.DiagnosticsContext = new CosmosDiagnosticsContextCore(); } - /// - public override string Message => this.ToString(); - /// /// The body of the cosmos response message as a string /// @@ -185,21 +186,36 @@ internal ResponseMessage ToCosmosResponseMessage(RequestMessage request) diagnostics: this.DiagnosticsContext); } + private static string GetMessageHelper( + HttpStatusCode statusCode, + int subStatusCode, + string responseBody, + string activityId) + { + StringBuilder stringBuilder = new StringBuilder(); + + stringBuilder.Append($"Response status code does not indicate success: "); + stringBuilder.Append($"{statusCode} ({(int)statusCode})"); + stringBuilder.Append("; Substatus: "); + stringBuilder.Append(subStatusCode); + stringBuilder.Append("; ActivityId: "); + stringBuilder.Append(activityId ?? string.Empty); + stringBuilder.Append("; Reason: ("); + stringBuilder.Append(responseBody ?? string.Empty); + stringBuilder.Append(");"); + + return stringBuilder.ToString(); + } + private string ToStringHelper( - StringBuilder stringBuilder) + StringBuilder stringBuilder) { if (stringBuilder == null) { throw new ArgumentNullException(nameof(stringBuilder)); } - stringBuilder.Append($"Response status code does not indicate success: "); - stringBuilder.Append($"{this.StatusCode} ({(int)this.StatusCode})"); - stringBuilder.Append("; Substatus: "); - stringBuilder.Append(this.SubStatusCode); - stringBuilder.Append("; Reason: ("); - stringBuilder.Append(this.ResponseBody); - stringBuilder.Append(");"); + stringBuilder.Append(this.Message); stringBuilder.AppendLine(); if (this.InnerException != null) diff --git a/Microsoft.Azure.Cosmos/src/Util/Extensions.cs b/Microsoft.Azure.Cosmos/src/Util/Extensions.cs index 9ef10d731b..c523b9f181 100644 --- a/Microsoft.Azure.Cosmos/src/Util/Extensions.cs +++ b/Microsoft.Azure.Cosmos/src/Util/Extensions.cs @@ -99,7 +99,7 @@ internal static ResponseMessage ToCosmosResponseMessage(this DocumentClientExcep subStatusCode: (int)SubStatusCodes.Unknown, responseTimeUtc: DateTime.UtcNow, requestCharge: cosmosException.Headers.RequestCharge, - errorMessage: cosmosException.Message, + errorMessage: documentClientException.ToString(), method: requestMessage?.Method, requestUri: requestMessage?.RequestUri, requestSessionToken: requestMessage?.Headers?.Session, diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs index b467dce52d..b00dafbfa2 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/CosmosItemTests.cs @@ -1258,7 +1258,7 @@ public async Task ItemRequestOptionAccessConditionTest() Assert.AreNotEqual(e.ActivityId, Guid.Empty); Assert.IsTrue(e.RequestCharge > 0); Assert.AreEqual($"{{{Environment.NewLine} \"Errors\": [{Environment.NewLine} \"One of the specified pre-condition is not met\"{Environment.NewLine} ]{Environment.NewLine}}}", e.ResponseBody); - string expectedMessage = $"Microsoft.Azure.Cosmos.CosmosException : Response status code does not indicate success: PreconditionFailed (412); Substatus: 0; Reason: ({{{Environment.NewLine} \"Errors\": [{Environment.NewLine} \"One of the specified pre-condition is not met\"{Environment.NewLine} ]{Environment.NewLine}}});{Environment.NewLine}{e.StackTrace}{Environment.NewLine}{e.Diagnostics.ToString()}"; + string expectedMessage = $"Response status code does not indicate success: PreconditionFailed (412); Substatus: 0; ActivityId: {e.ActivityId}; Reason: ({{{Environment.NewLine} \"Errors\": [{Environment.NewLine} \"One of the specified pre-condition is not met\"{Environment.NewLine} ]{Environment.NewLine}}});"; Assert.AreEqual(expectedMessage, e.Message); } finally diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TransportWrapperTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TransportWrapperTests.cs index 1e31baad08..f5399dc5a5 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TransportWrapperTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/TransportWrapperTests.cs @@ -94,7 +94,7 @@ private void ValidateTransportException(ResponseMessage responseMessage) { Assert.AreEqual(HttpStatusCode.ServiceUnavailable, responseMessage.StatusCode); string message = responseMessage.ErrorMessage; - Assert.AreEqual(responseMessage.ErrorMessage, responseMessage.CosmosException.ToString()); + Assert.AreEqual(responseMessage.ErrorMessage, responseMessage.CosmosException.Message); Assert.IsTrue(message.Contains("TransportException: A client transport error occurred: The connection failed"), "StoreResult Exception is missing"); string diagnostics = responseMessage.Diagnostics.ToString(); Assert.IsNotNull(diagnostics); diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosExceptionTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosExceptionTests.cs index 281e26475c..b39f13c294 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosExceptionTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosExceptionTests.cs @@ -111,7 +111,7 @@ public void VerifyDocumentClientExceptionToResponseMessage() Assert.AreEqual(HttpStatusCode.BadRequest, responseMessage.StatusCode); Assert.AreEqual(SubStatusCodes.WriteForbidden, responseMessage.Headers.SubStatusCode); Assert.IsTrue(responseMessage.ErrorMessage.Contains(errorMessage)); - Assert.IsTrue(responseMessage.ErrorMessage.Contains("VerifyDocumentClientExceptionToResponseMessage"), $"Message should have method name for the stack trace {responseMessage.ErrorMessage}"); + Assert.IsFalse(responseMessage.ErrorMessage.Contains("VerifyDocumentClientExceptionToResponseMessage"), $"Message should not have the stack trace {responseMessage.ErrorMessage}. StackTrace should be in Diagnostics."); } [TestMethod] @@ -143,21 +143,21 @@ public void VerifyTransportExceptionToResponseMessage() Assert.IsFalse(responseMessage.IsSuccessStatusCode); Assert.AreEqual(HttpStatusCode.ServiceUnavailable, responseMessage.StatusCode); Assert.IsTrue(responseMessage.ErrorMessage.Contains(errorMessage)); - Assert.IsTrue(responseMessage.ErrorMessage.Contains(transportException.ToString())); + Assert.IsFalse(responseMessage.ErrorMessage.Contains(transportException.ToString()), "InnerException tracked in Diagnostics"); } [TestMethod] public void EnsureCorrectStatusCode() { string testMessage = "Test" + Guid.NewGuid().ToString(); - + List<(HttpStatusCode statusCode, CosmosException exception)> exceptionsToStatusCodes = new List<(HttpStatusCode, CosmosException)>() { - (HttpStatusCode.NotFound, CosmosExceptionFactory.CreateNotFoundException(testMessage)), - (HttpStatusCode.InternalServerError, CosmosExceptionFactory.CreateInternalServerErrorException(testMessage)), - (HttpStatusCode.BadRequest, CosmosExceptionFactory.CreateBadRequestException(testMessage)), - (HttpStatusCode.RequestTimeout,CosmosExceptionFactory.CreateRequestTimeoutException(testMessage)), - ((HttpStatusCode)429, CosmosExceptionFactory.CreateThrottledException(testMessage)), + (HttpStatusCode.NotFound, CosmosExceptionFactory.CreateNotFoundException(testMessage, activityId: Guid.NewGuid().ToString())), + (HttpStatusCode.InternalServerError, CosmosExceptionFactory.CreateInternalServerErrorException(testMessage, activityId: Guid.NewGuid().ToString())), + (HttpStatusCode.BadRequest, CosmosExceptionFactory.CreateBadRequestException(testMessage, activityId: Guid.NewGuid().ToString())), + (HttpStatusCode.RequestTimeout,CosmosExceptionFactory.CreateRequestTimeoutException(testMessage, activityId: Guid.NewGuid().ToString())), + ((HttpStatusCode)429, CosmosExceptionFactory.CreateThrottledException(testMessage, activityId: Guid.NewGuid().ToString())), }; foreach((HttpStatusCode statusCode, CosmosException exception) item in exceptionsToStatusCodes) @@ -242,7 +242,7 @@ private void ValidateExceptionInfo( Assert.AreEqual(message, exception.ResponseBody); Assert.AreEqual(httpStatusCode, exception.StatusCode); Assert.IsTrue(exception.ToString().Contains(message)); - string expectedMessage = $"Microsoft.Azure.Cosmos.CosmosException : Response status code does not indicate success: {httpStatusCode} ({(int)httpStatusCode}); Substatus: 0; Reason: ({message});{Environment.NewLine}{exception.Diagnostics.ToString()}"; + string expectedMessage = $"Response status code does not indicate success: {httpStatusCode} ({(int)httpStatusCode}); Substatus: 0; ActivityId: {exception.ActivityId}; Reason: ({message});"; Assert.AreEqual(expectedMessage, exception.Message); } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/DotNetSDKAPI.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/DotNetSDKAPI.json index 12fd10c836..ef69c9e413 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/DotNetSDKAPI.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/DotNetSDKAPI.json @@ -1812,11 +1812,6 @@ ], "MethodInfo": "System.String get_ActivityId()" }, - "System.String get_Message()": { - "Type": "Method", - "Attributes": [], - "MethodInfo": "System.String get_Message()" - }, "System.String get_ResponseBody()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { "Type": "Method", "Attributes": [ @@ -1829,11 +1824,6 @@ "Attributes": [], "MethodInfo": "System.String get_StackTrace()" }, - "System.String Message": { - "Type": "Property", - "Attributes": [], - "MethodInfo": null - }, "System.String ResponseBody": { "Type": "Property", "Attributes": [],