Skip to content

Commit 88f6d58

Browse files
committed
fix: improve websocket close code handling
1 parent dfd4cc9 commit 88f6d58

File tree

1 file changed

+22
-8
lines changed

1 file changed

+22
-8
lines changed

DisCatSharp/Clients/DiscordClient.WebSocket.cs

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,10 @@ Task SocketOnException(IWebSocketClient sender, SocketErrorEventArgs e)
247247

248248
async Task SocketOnDisconnect(IWebSocketClient sender, SocketCloseEventArgs e)
249249
{
250-
// release session and connection
250+
var shouldReconnect = e.CloseCode is 4000 or 4001 or 4002 or 4003 or 4005 or 4007 or 4008 or 4009 or >= 5000;
251+
var shouldResume = e.CloseCode is 4000 or 4002 or 4008;
252+
var fatalError = e.CloseCode is 4004 or 4010 or 4011 or 4012 or 4013 or 4014;
253+
251254
this._connectionLock.Set();
252255
this._sessionLock.Set();
253256

@@ -257,18 +260,29 @@ async Task SocketOnDisconnect(IWebSocketClient sender, SocketCloseEventArgs e)
257260
this.Logger.LogDebug(LoggerEvents.ConnectionClose, "Connection closed ({CloseCode}, '{Reason}')", e.CloseCode, e.CloseMessage ?? "No reason given");
258261
await this._socketClosed.InvokeAsync(this, e).ConfigureAwait(false);
259262

260-
// TODO: We might need to include more 400X codes
261-
if (this.Configuration.AutoReconnect && e.CloseCode is < 4001 or >= 5000)
263+
if (fatalError)
264+
{
265+
this.Logger.LogCritical(LoggerEvents.ConnectionClose, "Fatal close code received ({CloseCode}, '{Reason}'). No reconnection attempt.", e.CloseCode, e.CloseMessage ?? "No reason given");
266+
return;
267+
}
268+
269+
if (shouldReconnect && !shouldResume)
270+
{
271+
this.Logger.LogWarning(LoggerEvents.ConnectionClose, "Session is invalid. Clearing session ID before reconnecting.");
272+
this._sessionId = null;
273+
}
274+
275+
if (this.Configuration.AutoReconnect && shouldReconnect)
262276
{
263277
this.Logger.LogCritical(LoggerEvents.ConnectionClose, "Connection terminated ({CloseCode}, '{Reason}'), reconnecting", e.CloseCode, e.CloseMessage ?? "No reason given");
264278
this._identified = false;
265279

266-
if (this._status is null)
267-
await this.ConnectAsync().ConfigureAwait(false);
268-
else if (this._status.IdleSince.HasValue)
269-
await this.ConnectAsync(this._status.ActivityInternal, this._status.Status, Utilities.GetDateTimeOffsetFromMilliseconds(this._status.IdleSince.Value)).ConfigureAwait(false);
280+
if (shouldResume && this._sessionId is not null)
281+
this.Logger.LogInformation(LoggerEvents.ConnectionClose, "Attempting to resume session with ID {SessionId}.", this._sessionId);
270282
else
271-
await this.ConnectAsync(this._status.ActivityInternal, this._status.Status).ConfigureAwait(false);
283+
this.Logger.LogWarning(LoggerEvents.ConnectionClose, "No valid session to resume, starting a new connection.");
284+
285+
await this.ConnectAsync(this._status?.ActivityInternal, this._status?.Status, this._status is not null && this._status.IdleSince.HasValue ? Utilities.GetDateTimeOffsetFromMilliseconds(this._status.IdleSince.Value) : null).ConfigureAwait(false);
272286
}
273287
else
274288
this.Logger.LogCritical(LoggerEvents.ConnectionClose, "Connection terminated ({CloseCode}, '{Reason}')", e.CloseCode, e.CloseMessage ?? "No reason given");

0 commit comments

Comments
 (0)