Skip to content

Commit 10190c2

Browse files
HandyS11claude
andcommitted
fix(discord): register slash commands off the gateway Ready handler
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 9084ad1 commit 10190c2

1 file changed

Lines changed: 32 additions & 13 deletions

File tree

src/RustPlusBot.Discord/DiscordBotService.cs

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -59,29 +59,48 @@ public async Task StopAsync(CancellationToken cancellationToken)
5959
await client.StopAsync().ConfigureAwait(false);
6060
}
6161

62-
private async Task OnReadyAsync()
62+
private Task OnReadyAsync()
6363
{
6464
// Ready fires on every gateway (re)connect; only register commands once per process.
65-
// Ready is dispatched serially on the gateway thread, so no synchronization is needed.
65+
// Ready is dispatched serially on the gateway thread, so no synchronization is needed —
66+
// set the flag before offloading so a re-fired Ready can't double-register.
6667
if (_hasRegisteredCommands)
6768
{
68-
return;
69+
return Task.CompletedTask;
6970
}
7071

71-
if (_options.ResetCommandsOnStartup)
72+
_hasRegisteredCommands = true;
73+
74+
// Registration is REST work (one call per guild); doing it inline blocks the gateway task
75+
// and stalls event dispatch, so offload it. Failures must be caught here — nothing awaits this.
76+
_ = Task.Run(RegisterCommandsAsync);
77+
return Task.CompletedTask;
78+
}
79+
80+
private async Task RegisterCommandsAsync()
81+
{
82+
try
7283
{
73-
await client.Rest.DeleteAllGlobalCommandsAsync().ConfigureAwait(false);
74-
logger.LogWarning(
75-
"ResetCommandsOnStartup is enabled: deleted all global application commands before registration.");
76-
}
84+
if (_options.ResetCommandsOnStartup)
85+
{
86+
await client.Rest.DeleteAllGlobalCommandsAsync().ConfigureAwait(false);
87+
logger.LogWarning(
88+
"ResetCommandsOnStartup is enabled: deleted all global application commands before registration.");
89+
}
90+
91+
foreach (var guild in client.Guilds)
92+
{
93+
await interactions.RegisterCommandsToGuildAsync(guild.Id).ConfigureAwait(false);
94+
}
7795

78-
foreach (var guild in client.Guilds)
96+
logger.LogInformation("Registered commands to {GuildCount} guild(s).", client.Guilds.Count);
97+
}
98+
#pragma warning disable CA1031 // Broad catch: fire-and-forget — an unobserved exception would vanish; log it instead.
99+
catch (Exception ex)
100+
#pragma warning restore CA1031
79101
{
80-
await interactions.RegisterCommandsToGuildAsync(guild.Id).ConfigureAwait(false);
102+
logger.LogError(ex, "Registering slash commands failed.");
81103
}
82-
83-
_hasRegisteredCommands = true;
84-
logger.LogInformation("Registered commands to {GuildCount} guild(s).", client.Guilds.Count);
85104
}
86105

87106
[SuppressMessage("Performance", "CA1859:Use concrete types when possible for improved performance",

0 commit comments

Comments
 (0)