dotnet / dotnet/MQTTnet

NullReferenceException in AcknowledgeReceivedPublishPacket

Open
#1,792 2 comments 6 reactions 0 assignees View on GitHub
bug
Dominant language
C#
Stars
5.1k
Forks
1.2k
PR merge metrics
No merged PRs in 30d

Description

### Describe the bug
Sometimes a `NullReferenceException` is thrown in the `AcknowledgeReceivedPublishPacket` method.

### Which component is your bug related to?
- Client

### To Reproduce
I'm not sure how to reproduce it and the issue is also kinda difficult to debug (it only ever happened on production...of course 🙄).

Basically the `AcknwoledgeReceivedPublishPacket` is sometimes (very rarely) throwing a `NullReferenceException`.

### Expected behavior
The `AcknowledgeAsync` method should never fail (but for a communication issue with the broker).

### Additional context / logging

We are using emqx as broker, with QoS=1 and we do use shared subscriptions.

This is the stack trace:
```batch
System.NullReferenceException: Object reference not set to an instance of an object. at MQTTnet.Client.MqttClient.AcknowledgeReceivedPublishPacket(MqttApplicationMessageReceivedEventArgs eventArgs, CancellationToken cancellationToken) at Silverback.Messaging.Broker.Mqtt.ConsumerChannelManager.HandleMessageAsync(ConsumedApplicationMessage consumedMessage) at Silverback.Messaging.Broker.Mqtt.ConsumerChannelManager.<>c__DisplayClass22_0.<b__0>d.MoveNext()"
```

### Code example

What I'm doing is pretty simple:

```csharp
// In the message handler I simply wrap the event args and write them into a queue
public async Task HandleApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs eventArgs)
{
var receivedMessage = new ConsumedApplicationMessage(eventArgs);

eventArgs.AutoAcknowledge = false;
await _channel.Writer.WriteAsync(receivedMessage).ConfigureAwait(false);
}

// After I process the message from the queue I call the `AcknowledgeAsync` method
private async Task HandleMessageAsync(ConsumedApplicationMessage consumedMessage)
{
// Retry locally until successfully processed (or skipped)
while (!_readCancellationTokenSource.Token.IsCancellationRequested)
{
await _mqttClientWrapper.HandleMessageAsync(consumedMessage).ConfigureAwait(false);

if (await consumedMessage.TaskCompletionSource.Task.ConfigureAwait(false))
{
await consumedMessage.EventArgs.AcknowledgeAsync(_readCancellationTokenSource.Token).ConfigureAwait(false);
break;
}

consumedMessage.TaskCompletionSource = new TaskCompletionSource();
}
}
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.