Create GetXXX utils wrapping try blocks

This commit is contained in:
Ske 2020-07-02 18:29:04 +02:00
parent 7fef8c1dde
commit c87e67245d
8 changed files with 95 additions and 49 deletions

View File

@ -15,7 +15,7 @@ namespace PluralKit.Bot
{
var text = ctx.PeekArgument();
if (text.TryParseMention(out var id))
return await ctx.Shard.GetUserAsync(id);
return await ctx.Shard.GetUser(id);
return null;
}
@ -116,25 +116,14 @@ namespace PluralKit.Bot
public static async Task<DiscordChannel> MatchChannel(this Context ctx)
{
if (!MentionUtils.TryParseChannel(ctx.PeekArgument(), out var channel))
if (!MentionUtils.TryParseChannel(ctx.PeekArgument(), out var id))
return null;
try
{
var discordChannel = await ctx.Shard.GetChannelAsync(channel);
if (discordChannel.Type != ChannelType.Text) return null;
ctx.PopArgument();
return discordChannel;
}
catch (NotFoundException)
{
return null;
}
catch (UnauthorizedException)
{
return null;
}
var channel = await ctx.Shard.GetChannel(id);
if (channel == null || channel.Type != ChannelType.Text) return null;
ctx.PopArgument();
return channel;
}
}
}

View File

@ -355,16 +355,11 @@ namespace PluralKit.Bot
{
// Try to resolve the user ID to find the associated account,
// so we can print their username.
try
{
var user = await ctx.Rest.GetUserAsync(id);
var user = await ctx.Shard.GetUser(id);
if (user != null)
return $"Account **{user.Username}#{user.Discriminator}** does not have a system registered.";
}
catch (NotFoundException)
{
// User not found, just return ID
else
return $"Account with ID `{id}` not found.";
}
}
return $"System with ID `{input}` not found.";

View File

@ -106,13 +106,13 @@ namespace PluralKit.Bot {
throw new PKSyntaxError($"Could not parse `{guildIdStr}` as an ID.");
// TODO: will this call break for sharding if you try to request a guild on a different bot instance?
guild = await ctx.Rest.GetGuildAsync(guildId);
guild = await ctx.Rest.GetGuild(guildId);
if (guild == null)
throw Errors.GuildNotFound(guildId);
}
// Ensure people can't query guilds they're not in + get their own permissions (for view access checking)
var senderGuildUser = await guild.GetMemberAsync(ctx.Author.Id);
var senderGuildUser = await guild.GetMember(ctx.Author.Id);
if (senderGuildUser == null)
throw new PKError("You must be a member of the guild you are querying.");

View File

@ -86,7 +86,7 @@ namespace PluralKit.Bot
private async ValueTask HandleQueryReaction(MessageReactionAddEventArgs evt, FullMessage msg)
{
// Try to DM the user info about the message
var member = await evt.Guild.GetMemberAsync(evt.User.Id);
var member = await evt.Guild.GetMember(evt.User.Id);
try
{
await member.SendMessageAsync(embed: await _embeds.CreateMemberEmbed(msg.System, msg.Member, evt.Guild, LookupContext.ByNonOwner));
@ -105,9 +105,9 @@ namespace PluralKit.Bot
// Check if the "pinger" has permission to send messages in this channel
// (if not, PK shouldn't send messages on their behalf)
var guildUser = await evt.Guild.GetMemberAsync(evt.User.Id);
var guildUser = await evt.Guild.GetMember(evt.User.Id);
var requiredPerms = Permissions.AccessChannels | Permissions.SendMessages;
if ((guildUser.PermissionsIn(evt.Channel) & requiredPerms) != requiredPerms) return;
if (guildUser == null || (guildUser.PermissionsIn(evt.Channel) & requiredPerms) != requiredPerms) return;
if (msg.System.PingsEnabled)
{

View File

@ -34,7 +34,7 @@ namespace PluralKit.Bot {
// Fetch/render info for all accounts simultaneously
var accounts = await conn.GetLinkedAccounts(system.Id);
var users = await Task.WhenAll(accounts.Select(async uid => (await client.GetUserAsync(uid))?.NameAndMention() ?? $"(deleted account {uid})"));
var users = await Task.WhenAll(accounts.Select(async uid => (await client.GetUser(uid))?.NameAndMention() ?? $"(deleted account {uid})"));
var memberCount = await conn.GetSystemMemberCount(system.Id, PrivacyLevel.Public);
var eb = new DiscordEmbedBuilder()
@ -159,18 +159,18 @@ namespace PluralKit.Bot {
{
var ctx = LookupContext.ByNonOwner;
var channel = await client.GetChannelAsync(msg.Message.Channel);
var serverMsg = channel != null ? await channel.GetMessageAsync(msg.Message.Mid) : null;
var channel = await client.GetChannel(msg.Message.Channel);
var serverMsg = channel != null ? await channel.GetMessage(msg.Message.Mid) : null;
// Need this whole dance to handle cases where:
// - the user is deleted (userInfo == null)
// - the bot's no longer in the server we're querying (channel == null)
// - the member is no longer in the server we're querying (memberInfo == null)
DiscordMember memberInfo = null;
DiscordUser userInfo = null;
if (channel != null) try { memberInfo = await channel.Guild.GetMemberAsync(msg.Message.Sender); } catch (NotFoundException) { }
DiscordUser userInfo = null;
if (channel != null) memberInfo = await channel.Guild.GetMember(msg.Message.Sender);
if (memberInfo != null) userInfo = memberInfo; // Don't do an extra request if we already have this info from the member lookup
else try { userInfo = await client.GetUserAsync(msg.Message.Sender); } catch (NotFoundException) { }
else userInfo = await client.GetUser(msg.Message.Sender);
// Calculate string displayed under "Sent by"
string userStr;

View File

@ -50,11 +50,9 @@ namespace PluralKit.Bot {
private async Task<DiscordChannel> FindLogChannel(ulong guild, ulong channel)
{
try
{
return await _rest.GetChannelAsync(channel);
}
catch (Exception e) when (e is NotFoundException || e is UnauthorizedException)
var obj = await _rest.GetChannel(channel);
if (obj == null)
{
// Channel doesn't exist or we don't have permission to access it, let's remove it from the database too
_logger.Warning("Attempted to fetch missing log channel {LogChannel}, removing from database", channel);
@ -63,7 +61,7 @@ namespace PluralKit.Bot {
new {Guild = guild});
}
return null;
return obj;
}
}
}

View File

@ -33,7 +33,7 @@ namespace PluralKit.Bot
public async Task<DiscordWebhook> GetWebhook(DiscordClient client, ulong channelId)
{
var channel = await client.GetChannelAsync(channelId);
var channel = await client.GetChannel(channelId);
if (channel == null) return null;
if (channel.Type == ChannelType.Text) return null;
return await GetWebhook(channel);

View File

@ -9,6 +9,7 @@ using System.Threading.Tasks;
using DSharpPlus;
using DSharpPlus.Entities;
using DSharpPlus.Exceptions;
using NodaTime;
@ -22,6 +23,10 @@ namespace PluralKit.Bot
public static DiscordColor Gray = new DiscordColor(0x979c9f);
public static Permissions DM_PERMISSIONS = (Permissions) 0b00000_1000110_1011100110000_000000;
private static readonly Regex USER_MENTION = new Regex("<@!?(\\d{17,19})>");
private static readonly Regex ROLE_MENTION = new Regex("<@&(\\d{17,19})>");
private static readonly Regex EVERYONE_HERE_MENTION = new Regex("@(everyone|here)");
private static readonly FieldInfo _roleIdsField = typeof(DiscordMember).GetField("_role_ids", BindingFlags.NonPublic | BindingFlags.Instance);
@ -58,7 +63,12 @@ namespace PluralKit.Bot
// Just delegates to PermissionsInSync, but handles the case of a non-member User in a guild properly
// This is a separate method because it requires an async call
if (channel.Guild != null && !(user is DiscordMember))
return PermissionsInSync(channel, await channel.Guild.GetMemberAsync(user.Id));
{
var member = await channel.Guild.GetMember(user.Id);
if (member != null)
return PermissionsInSync(channel, member);
}
return PermissionsInSync(channel, user);
}
@ -128,9 +138,6 @@ namespace PluralKit.Bot
return cache != null && cache.TryGetValue(id, out user);
}
private static readonly Regex USER_MENTION = new Regex("<@!?(\\d{17,19})>");
private static readonly Regex ROLE_MENTION = new Regex("<@&(\\d{17,19})>");
private static readonly Regex EVERYONE_HERE_MENTION = new Regex("@(everyone|here)");
public static DiscordColor? ToDiscordColor(this string color)
{
if (int.TryParse(color, NumberStyles.HexNumber, null, out var colorInt))
@ -184,5 +191,62 @@ namespace PluralKit.Bot
if (input != null) return pattern.Replace(input, @"\$&");
else return input;
}
public static Task<DiscordUser> GetUser(this DiscordRestClient client, ulong id) =>
WrapDiscordCall(client.GetUserAsync(id));
public static Task<DiscordUser> GetUser(this DiscordClient client, ulong id) =>
WrapDiscordCall(client.GetUserAsync(id));
public static Task<DiscordChannel> GetChannel(this DiscordRestClient client, ulong id) =>
WrapDiscordCall(client.GetChannelAsync(id));
public static Task<DiscordChannel> GetChannel(this DiscordClient client, ulong id) =>
WrapDiscordCall(client.GetChannelAsync(id));
public static Task<DiscordGuild> GetGuild(this DiscordRestClient client, ulong id) =>
WrapDiscordCall(client.GetGuildAsync(id));
public static Task<DiscordGuild> GetGuild(this DiscordClient client, ulong id) =>
WrapDiscordCall(client.GetGuildAsync(id));
public static Task<DiscordMember> GetMember(this DiscordRestClient client, ulong guild, ulong user)
{
async Task<DiscordMember> Inner() =>
await (await client.GetGuildAsync(guild)).GetMemberAsync(user);
return WrapDiscordCall(Inner());
}
public static Task<DiscordMember> GetMember(this DiscordClient client, ulong guild, ulong user)
{
async Task<DiscordMember> Inner() =>
await (await client.GetGuildAsync(guild)).GetMemberAsync(user);
return WrapDiscordCall(Inner());
}
public static Task<DiscordMember> GetMember(this DiscordGuild guild, ulong user) =>
WrapDiscordCall(guild.GetMemberAsync(user));
public static Task<DiscordMessage> GetMessage(this DiscordChannel channel, ulong id) =>
WrapDiscordCall(channel.GetMessageAsync(id));
public static Task<DiscordMessage> GetMessage(this DiscordRestClient client, ulong channel, ulong message) =>
WrapDiscordCall(client.GetMessageAsync(channel, message));
private static async Task<T> WrapDiscordCall<T>(Task<T> t)
where T: class
{
try
{
return await t;
}
catch (NotFoundException)
{
return null;
}
catch (UnauthorizedException)
{
return null;
}
}
}
}