Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

6.x client doesn't throw proper exception when input is too long for shortstr #907

Closed
bording opened this issue Jul 8, 2020 · 2 comments
Assignees
Labels
Milestone

Comments

@bording
Copy link
Collaborator

bording commented Jul 8, 2020

It looks like there's been a change/break in behavior around what the client does when encountering a value that is too large to fit into a shortstr.

Given the following code:

var factory = new ConnectionFactory();

using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
    var queueName = new string('q', 256);
    var result = channel.QueueDeclare(queueName, true, false, false);
 }

With version 5.2.0 and earlier you get the following exception thrown immediately:

RabbitMQ.Client.Exceptions.WireFormattingException: 'Short string too long; UTF-8 encoded length=256, max=255

With version 6.1.0, it appears to be hitting some timeout value:

System.TimeoutException: 'The operation has timed out.'

The stack trace of that exception:

   at RabbitMQ.Util.BlockingCell`1.WaitForValue(TimeSpan timeout)
   at RabbitMQ.Client.Impl.SimpleBlockingRpcContinuation.GetReply(TimeSpan timeout)
   at RabbitMQ.Client.Impl.ModelBase.QueueDeclare(String queue, Boolean passive, Boolean durable, Boolean exclusive, Boolean autoDelete, IDictionary`2 arguments)
   at RabbitMQ.Client.Impl.ModelBase.QueueDeclare(String queue, Boolean durable, Boolean exclusive, Boolean autoDelete, IDictionary`2 arguments)
   at RabbitMQ.Client.Impl.AutorecoveringModel.QueueDeclare(String queue, Boolean durable, Boolean exclusive, Boolean autoDelete, IDictionary`2 arguments)
   at RabbitMQ.Client.IModelExensions.QueueDeclare(IModel model, String queue, Boolean durable, Boolean exclusive, Boolean autoDelete, IDictionary`2 arguments)
   at ConsoleApp51.Program.Main(String[] args) in C:\Users\Brandon\source\repos\ConsoleApp51\ConsoleApp51\Program.cs:line 19

Looking at the network traffic, the client never sends anything when running into this on 6.1.0.

We should definitely be detecting if the input is too long to be written and throwing a more informative error, like it used to.

@bording
Copy link
Collaborator Author

bording commented Jul 8, 2020

I just checked the behavior of this with 6.2.0-rc.1, and it seems somewhat improved:

System.ArgumentException: 'The output byte buffer is too small to contain the encoded data, encoding 'Unicode (UTF-8)' fallback 'System.Text.EncoderReplacementFallback'. (Parameter 'bytes')'

But this is thrown from the internal guts of the framework:

   at System.Text.Encoding.ThrowBytesOverflow() in /_/src/System.Private.CoreLib/shared/System/Text/Encoding.cs:line 1190
   at System.Text.Encoding.ThrowBytesOverflow(EncoderNLS encoder, Boolean nothingEncoded) in /_/src/System.Private.CoreLib/shared/System/Text/Encoding.cs:line 1206
   at System.Text.Encoding.GetBytesWithFallback(ReadOnlySpan`1 chars, Int32 originalCharsLength, Span`1 bytes, Int32 originalBytesLength, EncoderNLS encoder) in /_/src/System.Private.CoreLib/shared/System/Text/Encoding.Internal.cs:line 689
   at System.Text.Encoding.GetBytesWithFallback(Char* pOriginalChars, Int32 originalCharCount, Byte* pOriginalBytes, Int32 originalByteCount, Int32 charsConsumedSoFar, Int32 bytesWrittenSoFar) in /_/src/System.Private.CoreLib/shared/System/Text/Encoding.Internal.cs:line 499
   at System.Text.UTF8Encoding.GetBytes(Char* chars, Int32 charCount, Byte* bytes, Int32 byteCount) in /_/src/System.Private.CoreLib/shared/System/Text/UTF8Encoding.cs:line 368
   at RabbitMQ.Client.Impl.WireFormatting.WriteShortstr(Span`1 span, String val)
   at RabbitMQ.Client.Impl.MethodArgumentWriter.WriteShortstr(String val)
   at RabbitMQ.Client.Framing.Impl.QueueDeclare.WriteArgumentsTo(MethodArgumentWriter& writer)
   at RabbitMQ.Client.Impl.Framing.Method.WriteTo(Span`1 span, UInt16 channel, MethodBase method)
   at RabbitMQ.Client.Impl.Command.Transmit(UInt16 channelNumber, Connection connection)
   at RabbitMQ.Client.Impl.SessionBase.Transmit(Command cmd)
   at RabbitMQ.Client.Impl.ModelBase.ModelSend(MethodBase method, ContentHeaderBase header, ReadOnlyMemory`1 body)
   at RabbitMQ.Client.Framing.Impl.Model._Private_QueueDeclare(String queue, Boolean passive, Boolean durable, Boolean exclusive, Boolean autoDelete, Boolean nowait, IDictionary`2 arguments)
   at RabbitMQ.Client.Impl.ModelBase.QueueDeclare(String queue, Boolean passive, Boolean durable, Boolean exclusive, Boolean autoDelete, IDictionary`2 arguments)
   at RabbitMQ.Client.Impl.ModelBase.QueueDeclare(String queue, Boolean durable, Boolean exclusive, Boolean autoDelete, IDictionary`2 arguments)
   at RabbitMQ.Client.Impl.AutorecoveringModel.QueueDeclare(String queue, Boolean durable, Boolean exclusive, Boolean autoDelete, IDictionary`2 arguments)
   at RabbitMQ.Client.IModelExensions.QueueDeclare(IModel model, String queue, Boolean durable, Boolean exclusive, Boolean autoDelete, IDictionary`2 arguments)
   at ConsoleApp51.Program.Main(String[] args) in C:\Users\Brandon\source\repos\ConsoleApp51\ConsoleApp51\Program.cs:line 19

This means the client is still not checking the length directly before trying to write it. The exceptions being thrown in 6.1.0 and 6.2.0 are not clear at all, and I wouldn't expect anyone using the client to understand what the problem is.

@lukebakken lukebakken added this to the 6.2.0 milestone Jul 14, 2020
@lukebakken lukebakken self-assigned this Jul 14, 2020
@lukebakken
Copy link
Contributor

Fixed by #908

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants