nats-io/nats.net.v2

Confusing Exception for NatsMemoryOwner<byte> with an empty payload

Closed this issue · 3 comments

Observed behavior

When trying to access the memory for NatsMemoryOwner like:

var resp = await sub.Msgs.ReadAsync(cancellationToken);
using (resp.Data)
{
    var x = Type.Parser.ParseFrom(resp.Data.Memory);
    ...
}

If the reponse payload was empty, I get the Exception:

System.ObjectDisposedException: The current buffer has already been disposed

at the point where Memory is accessed. Which is confusing.

This seems to be because NatsMemoryOwner treats a null _array as having been disposed. But in NatsMsg<T>.Build, an empty payload causes the NatsMemoryOwner to be created as default, which I would assume has null for the value of _array:

        var data = payloadBuffer.Length > 0
            ? serializer.Deserialize(payloadBuffer)
            : default;

Expected behavior

When decoding an empty payload, I would expect the NatsMemoryOwner<byte> to be the equivalent of an empty array. I would only expect an ObjectDisposedException if the struct had previously been disposed.

Server and client version

Client version 2.0.2

Host environment

No response

Steps to reproduce

Decode a message with empty payload as NatsMemoryOwner<byte>.

mtmk commented

I guess the workaround for now is to check the length

var resp = await sub.Msgs.ReadAsync(cancellationToken);
if (resp.Data.Length > 0)
{
  using (resp.Data)
  {
      var x = Type.Parser.ParseFrom(resp.Data.Memory);
      ...
  }
}

does that work for you?

Yes, that it what I ended up doing.

But that was after way too much time spent trying to work out how the NatsMemoryOwner had been disposed before I used it! The only way I worked it out in the end was by going through the Nats client source code. I'm just trying to save others from my pain :)

mtmk commented

Yes, that it what I ended up doing.

But that was after way too much time spent trying to work out how the NatsMemoryOwner had been disposed before I used it! The only way I worked it out in the end was by going through the Nats client source code. I'm just trying to save others from my pain :)

No you're absolutely right. I'm looking into it. just wanted to note a workaround now before we released a fix.

thank you for the detailed reports btw. very helpful 👍