azure-sdk-for-net: [BUG] Response.HasValue is inconsistent and returns unexpected results

Library name and version

Azure.Storage.Queues 12.13.1

Describe the bug

QueueClient.ReceiveMessageAsync returns a Response<QueueMessage> result, which is actually of type ValueResponse<T>. This internal class does NOT override the Response<T>.HasValue property.

As a result, when checking the HasValue property, it unexpectedly returns true, even if Value is false. This is misleading and led to broken app code based on this assumption.

Expected behavior

HasValue should reflect the current state of the Value property.

Actual behavior

It always returns true, regardless of whether or not Value has a value that is different from default(T).

Reproduction Steps

var response = await _queueClient.ReceiveMessageAsync();
if (!response.HasValue)
{
    // this block should not be entered if response.Value is default(T) but it is
}

Environment

No response

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 1
  • Comments: 16 (8 by maintainers)

Most upvoted comments

I think that’s the right choice. Any code that throws where it didn’t throw previously is a much poorer experience than a property that doesn’t actually reflect the current state.

My guess is that most devs are currently checking Value is null and, if it changes to throw, their code suddenly breaks without warning.

By implementing your suggestion of suppressing nullability checks and preserving Value functionality, while adding HasValue functionality, it is a net improvement, even if nullability checks suffer. And since anything else is too large of a breaking change, I’m not sure what else you could do other than modifying my original suggestion of an internal NullableValueResponse<T> type that handles the nullability check suppression and is returned as the public type. That said, I’m guessing that also is too large of a breaking change.

I appreciate the effort to come up with a creative solution!