container.ReadItemAsync<T> with matching IfNoneMatchEtag throws CosmosException (client v 3.3.2)
See original GitHub issueDescribe the bug Inconsistent behavior between ReadItemAsync and ReadItemStreamAsync when calling with an ItemRequestOptions containing a matching etag in IfNoneMatchEtag. ReadItemAsync throws a CosmosException and ReadItemStreamAsync returns a ResponseMessage with appropriate StatusCode set.
To Reproduce
- call container.ReadItemAsync<T> with matching IfNoneMatchEtag
- call container.ReadItemStreamAsync <T> with matching IfNoneMatchEtag
Expected behavior
- Both calls return a ResponseMessage with appropriate StatusCode set.
- Debatable - should IsSuccessStatusCode be True?
- Arguably, this specific scenario where the caller is supplying an ETAG should be considered a Successful result with status code 304 NotModified, since the implication is that we saved a transfer of the duplicate object over the wire.
Actual behavior -ReadItemAsync throws a CosmosException: “Response status code does not indicate success: 304 Substatus: 0 Reason: ().”
- ReadItemStreamAsync returns a ResponseMessage with NotModified StatusCode set and IsSuccessStatusCode == False.
Environment summary SDK Version: 3.3.2 OS Version: Windows,
Additional context callstack for CosmosExceptiom:
at Microsoft.Azure.Cosmos.ResponseMessage.EnsureSuccessStatusCode()
at Microsoft.Azure.Cosmos.CosmosResponseFactory.ToObjectInternal[T](ResponseMessage cosmosResponseMessage, CosmosSerializer jsonSerializer)
at Microsoft.Azure.Cosmos.CosmosResponseFactory.<CreateItemResponseAsync>b__6_0[T](ResponseMessage cosmosResponseMessage)
at Microsoft.Azure.Cosmos.CosmosResponseFactory.<ProcessMessageAsync>d__16`1.MoveNext()--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at UserQuery.<Main>d__0.MoveNext()
–
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (4 by maintainers)
Top Results From Across the Web
Container.ReadItemAsync<T> Method
A Task containing a ItemResponse<T> which wraps the read resource record. Exceptions. CosmosException. This exception can encapsulate many different types of ...
Read more >c# - Failure in Microsoft.Azure.Cosmos.Container. ...
The documentDBstorageid is simply a string which matches the document ID found in the database. The database does not use partition keys.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
My current workaround code, derived from reading the impl, in case it helps @davemanton
We were looking at using eTags to speed up queries to cosmos. We were interested in using this to return a not modified 304 response if someone sent a request with an eTag If-None-Match header to our api.
We found that using the ReadItemStreamAsync actually returned a slower response with a not modified response for the eTag than it did just to pull the whole object back using the same method.
When we looked into this we found that ReadItemStreamAsync threw an exception under the hood, it just hid it from the end result of the method by swallowing it.
I would not consider a 304 to be a failure state in any method as it’s a valid query result, particularly if you’re deliberately sending the eTag in the request options.
By throwing this exception it’s limiting the potential of cosmos for use with caching as the expense slows down the request to such an extent it makes it pointless to use the feature. This leaves us in the position where we need a second key store such as Redis and considerable extra work just to make use of eTags.
Are there any plans to stop using the EnsureSuccessStatusCode method to enable eTags to be used for more than concurrency?