discord-net / Discord.Net

An unofficial .Net wrapper for the Discord API (https://discord.com/)
https://discordnet.dev
MIT License
3.34k stars 737 forks source link

NullReferenceException sometimes occurs randomly when sending audio. #1674

Open F0903 opened 4 years ago

F0903 commented 4 years ago

Sometimes at random, a NullReferenceException gets thrown when sending audio. The stacktrace says it occurs in Discord.Net.Udp.DefaultUdpSocket.SendAsync().MoveNext(). I'm not sure how much help this is, but I only have a screenshot of the Visual Studio QuickWatch overview of the exception. If more information is needed I'll gladly try to get some more at request.

F0903 commented 4 years ago

Should also mention that I am using the latest dev version from MyGet

SubZero0 commented 4 years ago

Please, provide the full stacktrace.

F0903 commented 4 years ago

Please, provide the full stacktrace.

I shall do. It might take a bit though, as sometimes there can be hours between this error.

SubZero0 commented 4 years ago

I shall do. It might take a bit though, as sometimes there can be hours between this error.

Try to see if you get any other messages/exceptions following that, like a connection disconnect.

F0903 commented 4 years ago

I shall do. It might take a bit though, as sometimes there can be hours between this error.

Try to see if you get any other messages/exceptions following that, like a connection disconnect.

Sure. I usually run the bot inside Visual Studio, so it just pauses the program with a breakpoint. But I can try to press continue and see what more pops up.

F0903 commented 4 years ago

This is what the call stack window says at the point of exception: https://i.imgur.com/beX16YI.png

I don't know if there are better ways to get the stacktrace, if so feel free to say. 😅

F0903 commented 4 years ago

I also just wrote a quick line of code to print an unhandled exception to a text file, which produced the output underneath. I'm not sure if this is more useful than the picture above, or more accurate for that matter. The picture above and the breakpoint in visual studio shows a NullReferenceException, but this says TaskCanceledException.

System.Threading.Tasks.TaskCanceledException: A task was canceled. at Discord.Audio.Streams.BufferedWriteStream.WriteAsync(Byte[] data, Int32 offset, Int32 count, CancellationToken cancelToken) at Discord.Audio.Streams.OpusEncodeStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancelToken) at Discord.Audio.AudioStream.Write(Byte[] buffer, Int32 offset, Int32 count) at System.IO.Stream.Write(ReadOnlySpan`1 buffer) at Melodica.Services.Playback.Jukebox.<>c__DisplayClass38_0.b__1() in C:\dev\Programming\Melodica\Melodica\Services\Playback\Jukebox.cs:line 122 at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) --- End of stack trace from previous location where exception was thrown --- at System.Threading.ThreadHelper.ThreadStart()

F0903 commented 3 years ago

Is there any update on this? I just had this happen again. I am considering investigating it myself, but I haven't touched the internals of the lib before, so I am a bit hesitant. I apologize if this comment is redundant.

F0903 commented 3 years ago

@SubZero0 I forked the lib myself in an attempt to debug, and I just caught the error once again. It seems the _udp field in the DefaultUdpSocket class gets set to null randomly for some reason, which is what causes the exception when it tries to send data to a socket that is null.

I have a screenshot as well if it is of any further use.

For now, I have just wrapped it in a try/catch, where it sets _udp to a new instance. Gonna see if this works and then make a pull request.

I hope this is of use (?)

TJoshua commented 1 year ago

I debugged this as well (I have the same exact issue) and found that in my case the _udp field is getting set to null because the AudioClient's Disconnect event is getting raised with a "The server sent close 1000" exception. This exception is bubbled up from the underlying DefaultWebSocketClient, so it seems that the original exception in question is just a byproduct of a server disconnect (at least in my case). I'm still investigating why the server is closing the connection prematurely.