Improve error handling and reporting after command rewrite
This commit is contained in:
parent
284e8eb95a
commit
53ae0e3d70
@ -85,7 +85,8 @@ namespace PluralKit.Bot
|
||||
.AddSingleton<IDiscordClient, DiscordShardedClient>(_ => new DiscordShardedClient(new DiscordSocketConfig
|
||||
{
|
||||
MessageCacheSize = 5,
|
||||
ExclusiveBulkDelete = true
|
||||
ExclusiveBulkDelete = true,
|
||||
DefaultRetryMode = RetryMode.AlwaysRetry
|
||||
}))
|
||||
.AddSingleton<Bot>()
|
||||
.AddTransient<CommandTree>()
|
||||
@ -296,9 +297,10 @@ namespace PluralKit.Bot
|
||||
logger.Error(e, "Exception in bot event handler");
|
||||
|
||||
var evt = new SentryEvent(e);
|
||||
SentrySdk.CaptureEvent(evt, scope);
|
||||
|
||||
Console.Error.WriteLine(e);
|
||||
// Don't blow out our Sentry budget on sporadic not-our-problem erorrs
|
||||
if (e.IsOurProblem())
|
||||
SentrySdk.CaptureEvent(evt, scope);
|
||||
}
|
||||
}
|
||||
|
||||
@ -359,7 +361,17 @@ namespace PluralKit.Bot
|
||||
"select systems.* from systems, accounts where accounts.uid = @Id and systems.id = accounts.system",
|
||||
new {Id = msg.Author.Id});
|
||||
|
||||
await _tree.ExecuteCommand(new Context(_services, msg, argPos, system));
|
||||
try
|
||||
{
|
||||
await _tree.ExecuteCommand(new Context(_services, msg, argPos, system));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await HandleCommandError(msg, e);
|
||||
// HandleCommandError only *reports* the error, we gotta pass it through to the parent
|
||||
// error handler by rethrowing:
|
||||
throw;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -375,6 +387,22 @@ namespace PluralKit.Bot
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleCommandError(SocketUserMessage msg, Exception exception)
|
||||
{
|
||||
// This function *specifically* handles reporting a command execution error to the user.
|
||||
// We'll fetch the event ID and send a user-facing error message.
|
||||
// ONLY IF this error's actually our problem. As for what defines an error as "our problem",
|
||||
// check the extension method :)
|
||||
if (exception.IsOurProblem())
|
||||
{
|
||||
var eid = _services.GetService<EventIdProvider>().EventId;
|
||||
await msg.Channel.SendMessageAsync(
|
||||
$"{Emojis.Error} Internal error occurred. Please join the support server (https://discord.gg/PczBt78), and send the developer this ID: `{eid}`");
|
||||
}
|
||||
|
||||
// If not, don't care. lol.
|
||||
}
|
||||
|
||||
private void RegisterMessageMetrics(SocketMessage msg)
|
||||
{
|
||||
_metrics.Measure.Meter.Mark(BotMetrics.MessagesReceived);
|
||||
|
@ -86,6 +86,11 @@ namespace PluralKit.Bot.CommandSystem
|
||||
{
|
||||
await Reply($"{Emojis.Error} {e.Message}");
|
||||
}
|
||||
catch (TimeoutException e)
|
||||
{
|
||||
// Got a complaint the old error was a bit too patronizing. Hopefully this is better?
|
||||
await Reply($"{Emojis.Error} Operation timed out, sorry. Try again, perhaps?");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IUser> MatchUser()
|
||||
|
@ -2,9 +2,11 @@ using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Sockets;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Net;
|
||||
|
||||
using PluralKit.Core;
|
||||
using Image = SixLabors.ImageSharp.Image;
|
||||
@ -117,6 +119,24 @@ namespace PluralKit.Bot
|
||||
|
||||
public static async Task<bool> HasPermission(this IChannel channel, ChannelPermission permission) =>
|
||||
(await PermissionsIn(channel)).Has(permission);
|
||||
|
||||
public static bool IsOurProblem(this Exception e)
|
||||
{
|
||||
// This function filters out sporadic errors out of our control from being reported to Sentry
|
||||
// otherwise we'd blow out our error reporting budget as soon as Discord takes a dump, or something.
|
||||
|
||||
// Discord server errors are *not our problem*
|
||||
if (e is HttpException he && ((int) he.HttpCode) >= 500) return false;
|
||||
|
||||
// Socket errors are *not our problem*
|
||||
if (e is SocketException) return false;
|
||||
|
||||
// Tasks being cancelled for whatver reason are, you guessed it, also not our problem.
|
||||
if (e is TaskCanceledException) return false;
|
||||
|
||||
// This may expanded at some point.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
Loading…
Reference in New Issue
Block a user