-
-
Notifications
You must be signed in to change notification settings - Fork 741
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
[Bug]: Modifying a message with attachments when hitting rate limits attempts to read/close/read the stream passed in #2194
Comments
Does this still occur in 3.4.1? |
Yes it does, just hit this again |
I'm unable to reproduce this with this test code try
{
var channel = client.GetGuild(848176216011046962).GetTextChannel(869966873368858708);
var msg = await channel.SendFileAsync(new FileAttachment(@"C:\Users\lynch\Downloads\video0_6.mov", "boop.mov", "lmao"), "haha");
bool sus = false;
while (true)
{
var att = sus ? new FileAttachment(@"C:\Users\lynch\Downloads\video0_6.mov", "boop.mov", "lmao") : new FileAttachment(@"C:\Users\lynch\Downloads\flipped.png", "lmao.png", "what") ;
Console.WriteLine("Starting to modify");
await msg.ModifyAsync(x => x.Attachments = new FileAttachment[] { att });
Console.WriteLine("Stoping modify");
sus = !sus;
}
}
catch(Exception x)
{
Console.WriteLine(x);
} could you send some code over that hits this bug? |
Hmm, I am also having trouble reproing it right now as well. I think I was seeing actual rate limits being triggered as well, and I am worried I wasn't actually running 3.4.1 when it happened again |
So while I can't repro this in a test, it is definitely still happening with 3.4.1. I think it still has to do with not hitting pre-emptive rate limits, but getting rate limit responses from the discord server. |
I think I'm seeing this happen with 3.9.0; I'm copying messages from Slack over to a Discord server using I added some logging to my app and this is what it looks like when it happens (
There's a simple retry loop in my code that immediately retries a failed send up to 3 times, each time re-creating the I'm sure that I could get around this by setting my loop up to wait until the rate limit timer has elapsed, which is what I'll try next, but I think it would be safest if the API did it for me. |
I've done some more investigating and I think this happens because request parameters are disposed of after the first attempt, regardless of whether it was a successful request. That disposal makes sense because all of the content gets dumped in a
I think we both were seeing this with rate limiting because a 429 is one the few cases where a request is guaranteed to be re-sent with the exact same parameters. But we can actually replicate this bug with a much simpler case that reuses a param intentionally: var webhookClient = new DiscordWebhookClient(...);
var fileAttachment = new FileAttachment(pathToFile);
// Reuse the same FileAttachment object for two messages
await webhookClient.SendFileAsync(fileAttachment, "Message 1");
await webhookClient.SendFileAsync(fileAttachment, "Message 2"); @quinchs I think your code sample was failing to repro because it was relying only on the 429 rate limit getting triggered correctly, and maybe it wasn't (see #2642). And you were creating a new I think the solution here is to not provide the exact |
Check The Docs
Verify Issue Source
Check your intents
Description
When calling ModifyMessageAsync and attempting to change/add attachments, if you are getting rate limited the stream you pass in will be read, sent to discord and then disposed when you get the rate limit error. It will then try to send it again, which will attempt to re-read the stream, which will fail for most streams. To work around this, I wrapped my stream in a wrapper that claimed it was not seekable, since the d.net code will copy a non-seekable stream to its own memoryStream and use (and dispose) that stream.
Version
3.3.2
Working Version
No response
Logs
System.ObjectDisposedException: Cannot access a closed Stream.
at System.IO.StreamHelpers.ValidateCopyToArgs(Stream source, Stream destination, Int32 bufferSize)
at System.IO.MemoryStream.CopyToAsync(Stream destination, Int32 bufferSize, CancellationToken cancellationToken)
at Discord.Net.Rest.DefaultRestClient.SendAsync(String method, String endpoint, IReadOnlyDictionary2 multipartParams, CancellationToken cancelToken, Boolean headerOnly, String reason)
at Discord.Net.Queue.MultipartRestRequest.SendAsync()
at Discord.Net.Queue.RequestBucket.SendAsync(RestRequest request)
at Discord.Net.Queue.RequestQueue.SendAsync(RestRequest request)
at Discord.API.DiscordRestApiClient.SendInternalAsync(String method, String endpoint, RestRequest request)
at Discord.API.DiscordRestApiClient.SendMultipartAsync[TResponse](String method, String endpoint, IReadOnlyDictionary2 multipartArgs, BucketId bucketId, ClientBucketType clientBucket, RequestOptions options)
at Discord.API.DiscordRestApiClient.ModifyMessageAsync(UInt64 channelId, UInt64 messageId, UploadFileParams args, RequestOptions options)
at Discord.Rest.MessageHelper.ModifyAsync(UInt64 channelId, UInt64 msgId, BaseDiscordClient client, Action1 func, RequestOptions options)
at Discord.Rest.ChannelHelper.ModifyMessageAsync(IMessageChannel channel, UInt64 messageId, Action1 func, BaseDiscordClient client, RequestOptions options)
at Discord.WebSocket.SocketTextChannel.ModifyMessageAsync(UInt64 messageId, Action`1 func, RequestOptions options)
Sample
Packages
None
The text was updated successfully, but these errors were encountered: