Azure-cosmos-dotnet-v3: NullReferenceException on Gateway mode on WebAssembly

Created on 24 Sep 2020  路  4Comments  路  Source: Azure/azure-cosmos-dotnet-v3

When doing a point operation over a non- existent container generates a NullReferenceException.

Steps to reproduce

CosmosClientOptions cosmosClientOptions = new CosmosClientOptions
{
    ConnectionMode = ConnectionMode.Gateway
};
CosmosClient cl = new CosmosClient("<connectionstring>", cosmosClientOptions);
await client.GetContainer("notExists", "notExists").CreateItem(new { id = "test" }, new PartitionKey("test"));

Yields this stack trace:

System.NullReferenceException: Object reference not set to an instance of an object.
  at Microsoft.Azure.Cosmos.GatewayStoreClient.CreateDocumentClientExceptionAsync (System.Net.Http.HttpResponseMessage responseMessage, Microsoft.Azure.Documents.IClientSideRequestStatistics requestStatistics) [0x00039] in C:\GIT\azure-cosmos-dotnet-v3\Microsoft.Azure.Cosmos\src\GatewayStoreClient.cs:177 
  at Microsoft.Azure.Cosmos.GatewayStoreClient.ParseResponseAsync (System.Net.Http.HttpResponseMessage responseMessage, Newtonsoft.Json.JsonSerializerSettings serializerSettings, Microsoft.Azure.Documents.DocumentServiceRequest request) [0x00241] in C:\GIT\azure-cosmos-dotnet-v3\Microsoft.Azure.Cosmos\src\GatewayStoreClient.cs:117 
  at Microsoft.Azure.Cosmos.GatewayStoreClient.InvokeAsync (Microsoft.Azure.Documents.DocumentServiceRequest request, Microsoft.Azure.Documents.ResourceType resourceType, System.Uri physicalAddress, System.Threading.CancellationToken cancellationToken) [0x000eb] in C:\GIT\azure-cosmos-dotnet-v3\Microsoft.Azure.Cosmos\src\GatewayStoreClient.cs:47 
  at Microsoft.Azure.Cosmos.GatewayStoreModel.ProcessMessageAsync (Microsoft.Azure.Documents.DocumentServiceRequest request, System.Threading.CancellationToken cancellationToken) [0x000ac] in C:\GIT\azure-cosmos-dotnet-v3\Microsoft.Azure.Cosmos\src\GatewayStoreModel.cs:61 
  at Microsoft.Azure.Cosmos.Routing.ClientCollectionCache.ReadCollectionAsync (System.String collectionLink, System.Threading.CancellationToken cancellationToken, Microsoft.Azure.Cosmos.IDocumentClientRetryPolicy retryPolicyInstance) [0x001da] in C:\GIT\azure-cosmos-dotnet-v3\Microsoft.Azure.Cosmos\src\Routing\ClientCollectionCache.cs:86 
  at Microsoft.Azure.Documents.BackoffRetryUtility`1[T].ExecuteRetryAsync (System.Func`1[TResult] callbackMethod, System.Func`3[T1,T2,TResult] callShouldRetry, System.Func`1[TResult] inBackoffAlternateCallbackMethod, System.TimeSpan minBackoffForInBackoffCallback, System.Threading.CancellationToken cancellationToken, System.Action`1[T] preRetryCallback) <0x3d80510 + 0x000e6> in <filename unknown>:0 
  at Microsoft.Azure.Documents.ShouldRetryResult.ThrowIfDoneTrying (System.Runtime.ExceptionServices.ExceptionDispatchInfo capturedException) <0x3e03438 + 0x00022> in <filename unknown>:0 
  at Microsoft.Azure.Documents.BackoffRetryUtility`1[T].ExecuteRetryAsync (System.Func`1[TResult] callbackMethod, System.Func`3[T1,T2,TResult] callShouldRetry, System.Func`1[TResult] inBackoffAlternateCallbackMethod, System.TimeSpan minBackoffForInBackoffCallback, System.Threading.CancellationToken cancellationToken, System.Action`1[T] preRetryCallback) <0x3d80510 + 0x002c8> in <filename unknown>:0 
  at Microsoft.Azure.Cosmos.Common.CollectionCache+<>c__DisplayClass10_0.<ResolveByNameAsync>b__0 () [0x00064] in C:\GIT\azure-cosmos-dotnet-v3\Microsoft.Azure.Cosmos\src\Routing\CollectionCache.cs:253 
  at Microsoft.Azure.Cosmos.Common.AsyncCache`2[TKey,TValue].GetAsync (TKey key, TValue obsoleteValue, System.Func`1[TResult] singleValueInitFunc, System.Threading.CancellationToken cancellationToken, System.Boolean forceRefresh) [0x002ec] in C:\GIT\azure-cosmos-dotnet-v3\Microsoft.Azure.Cosmos\src\Routing\AsyncCache.cs:147 
  at Microsoft.Azure.Cosmos.Common.CollectionCache.ResolveByNameAsync (System.String apiVersion, System.String resourceAddress, System.Threading.CancellationToken cancellationToken) [0x000dc] in C:\GIT\azure-cosmos-dotnet-v3\Microsoft.Azure.Cosmos\src\Routing\CollectionCache.cs:247 
  at Microsoft.Azure.Cosmos.ContainerCore.GetCachedContainerPropertiesAsync (System.Threading.CancellationToken cancellationToken) [0x000d3] in C:\GIT\azure-cosmos-dotnet-v3\Microsoft.Azure.Cosmos\src\Resource\Container\ContainerCore.cs:313 

SDK 3.13.0 running on Blazor Web Assembly

Can't repro on a normal NET Core application, but it seems the NRE comes from this line:

string resourceLink = responseMessage.RequestMessage.RequestUri.LocalPath;, responseMessage.RequestMessage seems to be null.

bug

All 4 comments

Apparently HttpClient in WASM does not set the HttpResponseMessage.RequestMessage property when SendAsync is called.

HttpResponseMessage responseMessage = await this.httpClient.SendAsync(
        requestMessage,
        HttpCompletionOption.ResponseHeadersRead,
        cancellationToken);

After this call, responseMessage.RequestMessage is null in WASM, but not null in normal NET Core.

One potential quick fix would be to add this on CosmosHttpClientCore:

HttpResponseMessage responseMessage = await this.httpClient.SendAsync(
        requestMessage,
        HttpCompletionOption.ResponseHeadersRead,
        cancellationToken);

if (responseMessage.RequestMessage == null)
{
    responseMessage.RequestMessage = requestMessage;
}

@j82w What do you think? I'm trying to create a small repro for the NET team and will file it in their repo.

Filing in their repo is fine - but this would take forever to get rolled out. So making the change proposed to safe-guard in our code is definitely a good choice.

I agree that we should file it on their repo, but also do the fix the SDK to unblock users.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

darthmolen picture darthmolen  路  4Comments

ealsur picture ealsur  路  8Comments

JeremyLikness picture JeremyLikness  路  7Comments

Liversage picture Liversage  路  7Comments

gegoodwin picture gegoodwin  路  7Comments