diff --git a/Microsoft.Azure.Cosmos/src/Batch/TransactionalBatchResponse.cs b/Microsoft.Azure.Cosmos/src/Batch/TransactionalBatchResponse.cs index c5bdae56d2..ce28d3adaf 100644 --- a/Microsoft.Azure.Cosmos/src/Batch/TransactionalBatchResponse.cs +++ b/Microsoft.Azure.Cosmos/src/Batch/TransactionalBatchResponse.cs @@ -211,7 +211,8 @@ IEnumerator IEnumerable.GetEnumerator() internal static async Task FromResponseMessageAsync( ResponseMessage responseMessage, ServerBatchRequest serverRequest, - CosmosSerializer serializer) + CosmosSerializer serializer, + bool shouldPromoteOperationStatus = true) { using (responseMessage) { @@ -230,7 +231,13 @@ internal static async Task FromResponseMessageAsync( if (content.ReadByte() == (int)HybridRowVersion.V1) { content.Position = 0; - response = await TransactionalBatchResponse.PopulateFromContentAsync(content, responseMessage, serverRequest, serializer); + response = await TransactionalBatchResponse.PopulateFromContentAsync( + content, + responseMessage, + serverRequest, + serializer, + shouldPromoteOperationStatus); + if (response == null) { // Convert any payload read failures as InternalServerError @@ -247,7 +254,8 @@ internal static async Task FromResponseMessageAsync( } } } - else + + if (response == null) { response = new TransactionalBatchResponse( responseMessage.StatusCode, @@ -317,7 +325,8 @@ private static async Task PopulateFromContentAsync( Stream content, ResponseMessage responseMessage, ServerBatchRequest serverRequest, - CosmosSerializer serializer) + CosmosSerializer serializer, + bool shouldPromoteOperationStatus) { List results = new List(); @@ -348,7 +357,8 @@ record => // Promote the operation error status as the Batch response error status if we have a MultiStatus response // to provide users with status codes they are used to. - if ((int)responseMessage.StatusCode == (int)StatusCodes.MultiStatus) + if ((int)responseMessage.StatusCode == (int)StatusCodes.MultiStatus + && shouldPromoteOperationStatus) { foreach (TransactionalBatchOperationResult result in results) { diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchUnitTests.cs index 09fd1040cd..92fb330821 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchUnitTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Batch/BatchUnitTests.cs @@ -9,6 +9,7 @@ namespace Microsoft.Azure.Cosmos.Tests using System.IO; using System.Linq; using System.Net; + using System.Text; using System.Threading; using System.Threading.Tasks; using Microsoft.Azure.Cosmos.Client.Core.Tests; @@ -338,6 +339,33 @@ public async Task BatchSingleServerResponseAsync() Assert.IsNull(batchResponse[1].ResourceStream); } + [TestMethod] + [Owner("abpai")] + public async Task BatchJsonServerResponseAsync() + { + TestHandler testHandler = new TestHandler((request, cancellationToken) => + { + HttpStatusCode serverStatusCode = HttpStatusCode.Gone; + Stream serverContent = new MemoryStream(Encoding.UTF8.GetBytes("{ \"random\": 1 }")); + + ResponseMessage responseMessage = new ResponseMessage(serverStatusCode, requestMessage: null, errorMessage: null) + { + Content = serverContent + }; + + return Task.FromResult(responseMessage); + }); + + Container container = BatchUnitTests.GetContainer(testHandler); + + TransactionalBatchResponse batchResponse = await new BatchCore((ContainerCore)container, new Cosmos.PartitionKey(BatchUnitTests.PartitionKey1)) + .ReadItem("id1") + .ReadItem("id2") + .ExecuteAsync(); + + Assert.AreEqual(HttpStatusCode.Gone, batchResponse.StatusCode); + } + /// /// Test to make sure IsFeedRequest is true for Batch operation /// diff --git a/changelog.md b/changelog.md index 4c82d39af7..641d0ea60c 100644 --- a/changelog.md +++ b/changelog.md @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - [#1075](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/1075) Including header size details for BadRequest with large headers - +- [#1086](https://github.com/Azure/azure-cosmos-dotnet-v3/pull/1086) Fix possible NullReferenceException on a TransactionalBatch code path ### Fixed