Azure / azure-amqp

AMQP C# library
Other
94 stars 70 forks source link

[BUG] AmqpTransportInitiator.Complete is throwing a NullReferenceException #258

Closed Chocanto closed 4 months ago

Chocanto commented 4 months ago

Hi,

After updating to the latest version (2.6.5) of Microsoft.Azure.Amqp (included in azure.messaging.servicebus starting 7.17.4) we are seeing more and more NullReferenceException being thrown when the internet connection is unstable. This makes our application crash multiple times per day.

We were not seeing this error at all in the previous versions.

We wonder if this bug could have been introduced in this commit: 843ab89. In particular the piece of code added in Microsoft.Azure.Amqp/Amqp/Transport/AmqpTransportInitiator.cs to change the type of exception when catching an ObjectDisposedException.

Please find below a stack trace of this exception:

Unhandled exception. Microsoft.Azure.Amqp.CallbackException: An AsyncCallback threw an exception.
 ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Azure.Amqp.Transport.AmqpTransportInitiator.Complete(TransportAsyncCallbackArgs args)
   at Microsoft.Azure.Amqp.Transport.AmqpTransportInitiator.OnTransportOpenCompete(IAsyncResult result)
   at Microsoft.Azure.Amqp.AsyncResult.TryComplete(Boolean didCompleteSynchronously, Exception exception)
   --- End of inner exception stack trace ---
   at Microsoft.Azure.Amqp.AsyncResult.TryComplete(Boolean didCompleteSynchronously, Exception exception)
   at Microsoft.Azure.Amqp.AmqpObject.CompleteOpen(Boolean syncComplete, Exception exception)
   at Microsoft.Azure.Amqp.Sasl.SaslTransport.OnNegotiationFail(Exception exception)
   at Microsoft.Azure.Amqp.Sasl.SaslNegotiator.CompleteTransport()
   at Microsoft.Azure.Amqp.Sasl.SaslNegotiator.HandleException(String action, Exception exception)
   at Microsoft.Azure.Amqp.Sasl.SaslNegotiator.Microsoft.Azure.Amqp.IIoHandler.OnIoFault(Exception exception)
   at Microsoft.Azure.Amqp.AsyncIO.FrameBufferReader.HandleReadComplete(TransportAsyncCallbackArgs args)
   at Microsoft.Azure.Amqp.AsyncIO.FrameBufferReader.ReadCore(TransportAsyncCallbackArgs args)
   at Microsoft.Azure.Amqp.AsyncIO.FrameBufferReader.ReadFrame()
   at Microsoft.Azure.Amqp.Sasl.SaslNegotiator.ReadFrame()
   at Microsoft.Azure.Amqp.Sasl.SaslNegotiator.OnWriteFrameComplete(TransportAsyncCallbackArgs args)
   at Microsoft.Azure.Amqp.AsyncIO.AsyncBufferWriter.HandleWriteComplete(TransportAsyncCallbackArgs args)
   at Microsoft.Azure.Amqp.AsyncIO.AsyncBufferWriter.Write(TransportAsyncCallbackArgs args)
   at Microsoft.Azure.Amqp.AsyncIO.AsyncBufferWriter.WriteBuffer(TransportAsyncCallbackArgs args)
   at Microsoft.Azure.Amqp.Sasl.SaslNegotiator.WriteFrame(Performative command, Boolean needReply)
   at Microsoft.Azure.Amqp.Sasl.SaslAnonymousHandler.OnStart(SaslInit init, Boolean isClient)
   at Microsoft.Azure.Amqp.Sasl.SaslHandler.Start(SaslNegotiator saslNegotiator, SaslInit init, Boolean isClient)
   at Microsoft.Azure.Amqp.Sasl.SaslNegotiator.OnSaslServerMechanisms(SaslMechanisms mechanisms)
   at Microsoft.Azure.Amqp.Sasl.SaslNegotiator.HandleSaslCommand(Performative command)
   at Microsoft.Azure.Amqp.Sasl.SaslNegotiator.Microsoft.Azure.Amqp.IIoHandler.OnReceiveBuffer(ByteBuffer buffer)
   at Microsoft.Azure.Amqp.AsyncIO.FrameBufferReader.HandleReadComplete(TransportAsyncCallbackArgs args)
   at Microsoft.Azure.Amqp.AsyncIO.FrameBufferReader.ReadCore(TransportAsyncCallbackArgs args)
   at Microsoft.Azure.Amqp.AsyncIO.FrameBufferReader.ReadFrame()
   at Microsoft.Azure.Amqp.Sasl.SaslNegotiator.ReadFrame()
   at Microsoft.Azure.Amqp.Sasl.SaslNegotiator.Start()
   at Microsoft.Azure.Amqp.Sasl.SaslTransport.OpenInternal()
   at Microsoft.Azure.Amqp.AmqpObject.OpenAsyncResult.OnStart()
   at Microsoft.Azure.Amqp.AmqpObject.AmqpObjectAsyncResult.Start()
   at Microsoft.Azure.Amqp.AmqpObject.BeginOpen(TimeSpan timeout, CancellationToken cancellationToken, AsyncCallback callback, Object state)
   at Microsoft.Azure.Amqp.AmqpObject.BeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
   at Microsoft.Azure.Amqp.Transport.AmqpTransportInitiator.OnReadHeaderComplete(TransportAsyncCallbackArgs args)
   at Microsoft.Azure.Amqp.AsyncIO.AsyncBufferReader.HandleReadComplete(TransportAsyncCallbackArgs args)
   at Microsoft.Azure.Amqp.AsyncIO.AsyncBufferReader.OnReadComplete(TransportAsyncCallbackArgs args)
   at Microsoft.Azure.Amqp.Transport.TlsTransport.HandleOperationComplete(IAsyncResult result, Boolean write, Boolean syncComplete)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task& currentTask)

Thank you for your help!

xinchen10 commented 4 months ago

Thanks for reporting the issue. Yes your analysis is correct. It should be a regression from the exception conversion change. We will fix it and release a new package.

xinchen10 commented 4 months ago

Released 2.6.6

Chocanto commented 4 months ago

Thank you very much for this quick fix!