From 5983148d1aa205e10e6ebd98acf74048bcb36d58 Mon Sep 17 00:00:00 2001 From: Vankka Date: Fri, 21 Jun 2024 15:54:09 +0300 Subject: [PATCH] Improve error logging in mirroring --- .../discord/util/DiscordPermissionUtil.java | 6 ++-- .../common/logging/impl/DiscordSRVLogger.java | 32 +++++++++++++---- .../DiscordMessageMirroringModule.java | 35 ++++++++++++++++--- 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/common/src/main/java/com/discordsrv/common/discord/util/DiscordPermissionUtil.java b/common/src/main/java/com/discordsrv/common/discord/util/DiscordPermissionUtil.java index 2beca28c..b9a3a1d0 100644 --- a/common/src/main/java/com/discordsrv/common/discord/util/DiscordPermissionUtil.java +++ b/common/src/main/java/com/discordsrv/common/discord/util/DiscordPermissionUtil.java @@ -23,7 +23,7 @@ public final class DiscordPermissionUtil { channel = ((ThreadChannel) channel).getParentChannel(); } EnumSet missingPermissions = checkMissingPermissions(channel, permissions); - return format(missingPermissions, "#" + channel.getName()); + return createErrorMessage(missingPermissions, "#" + channel.getName()); } public static EnumSet checkMissingPermissions(GuildChannel channel, Collection permissions) { @@ -45,7 +45,7 @@ public final class DiscordPermissionUtil { public static String missingPermissionsString(Guild guild, Collection permissions) { EnumSet missingPermissions = checkMissingPermissions(guild, permissions); - return format(missingPermissions, guild.getName()); + return createErrorMessage(missingPermissions, guild.getName()); } public static EnumSet checkMissingPermissions(Guild guild, Collection permissions) { @@ -58,7 +58,7 @@ public final class DiscordPermissionUtil { return missingPermissions; } - private static String format(EnumSet permissions, String where) { + public static String createErrorMessage(EnumSet permissions, String where) { if (permissions.isEmpty()) { return null; } diff --git a/common/src/main/java/com/discordsrv/common/logging/impl/DiscordSRVLogger.java b/common/src/main/java/com/discordsrv/common/logging/impl/DiscordSRVLogger.java index 011d5ee3..67b2253b 100644 --- a/common/src/main/java/com/discordsrv/common/logging/impl/DiscordSRVLogger.java +++ b/common/src/main/java/com/discordsrv/common/logging/impl/DiscordSRVLogger.java @@ -21,9 +21,13 @@ package com.discordsrv.common.logging.impl; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.config.main.DebugConfig; import com.discordsrv.common.config.main.MainConfig; +import com.discordsrv.common.discord.util.DiscordPermissionUtil; import com.discordsrv.common.logging.LogLevel; import com.discordsrv.common.logging.Logger; +import net.dv8tion.jda.api.JDA; import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.channel.middleman.GuildChannel; import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; import org.apache.commons.lang3.exception.ExceptionUtils; import org.jetbrains.annotations.NotNull; @@ -38,10 +42,7 @@ import java.nio.file.StandardOpenOption; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.time.Duration; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Queue; +import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Future; @@ -125,8 +126,27 @@ public class DiscordSRVLogger implements Logger { throwable = null; } if (throwable instanceof InsufficientPermissionException) { - Permission permission = ((InsufficientPermissionException) throwable).getPermission(); - String msg = "The bot is missing the \"" + permission.getName() + "\" permission"; + InsufficientPermissionException exception = (InsufficientPermissionException) throwable; + Permission permission = exception.getPermission(); + + JDA jda = discordSRV.jda(); + GuildChannel guildChannel = jda != null ? exception.getChannel(jda) : null; + long channelId = exception.getChannelId(); + Guild guild = jda != null ? exception.getGuild(jda) : null; + long guildId = exception.getGuildId(); + + String where; + if (guildChannel != null) { + where = "#" + guildChannel.getName(); + } else if (channelId != 0) { + where = "Channel ID " + Long.toUnsignedString(channelId); + } else if (guild != null) { + where = guild.getName(); + } else { + where = "Server ID " + Long.toUnsignedString(guildId); + } + + String msg = DiscordPermissionUtil.createErrorMessage(EnumSet.of(permission), where); if (message == null) { message = msg; } else { diff --git a/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordMessageMirroringModule.java b/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordMessageMirroringModule.java index 097c8de2..a0d57096 100644 --- a/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordMessageMirroringModule.java +++ b/common/src/main/java/com/discordsrv/common/messageforwarding/discord/DiscordMessageMirroringModule.java @@ -41,11 +41,14 @@ import com.discordsrv.common.config.main.channels.MirroringConfig; import com.discordsrv.common.config.main.channels.base.BaseChannelConfig; import com.discordsrv.common.config.main.channels.base.IChannelConfig; import com.discordsrv.common.config.main.generic.DiscordIgnoresConfig; +import com.discordsrv.common.discord.util.DiscordPermissionUtil; import com.discordsrv.common.future.util.CompletableFutureUtil; import com.discordsrv.common.logging.NamedLogger; import com.discordsrv.common.module.type.AbstractModule; import com.github.benmanes.caffeine.cache.Cache; +import net.dv8tion.jda.api.Permission; import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.channel.middleman.GuildMessageChannel; import okhttp3.Request; import okhttp3.Response; import okhttp3.ResponseBody; @@ -57,6 +60,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.*; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; import java.util.concurrent.TimeUnit; public class DiscordMessageMirroringModule extends AbstractModule { @@ -171,7 +175,7 @@ public class DiscordMessageMirroringModule extends AbstractModule { ); } - CompletableFutureUtil.combine(futures).whenComplete((lists, t) -> { + CompletableFutureUtil.combine(futures).whenComplete((lists, v) -> { Set channelIdsHandled = new HashSet<>(); for (MirrorOperation operation : lists) { List> mirrorFutures = new ArrayList<>(); @@ -214,13 +218,23 @@ public class DiscordMessageMirroringModule extends AbstractModule { return; } + GuildMessageChannel channel = (GuildMessageChannel) mirrorChannel.getAsJDAMessageChannel(); + String missingPermissions = DiscordPermissionUtil.missingPermissionsString(channel, Permission.VIEW_CHANNEL, Permission.MANAGE_WEBHOOKS); + if (missingPermissions != null) { + logger().error("Failed to mirror message to " + describeChannel(mirrorChannel) + ": " + missingPermissions); + continue; + } + CompletableFuture future = mirrorChannel.sendMessage(messageBuilder.build()) .thenApply(msg -> new MirroredMessage(msg, config)); mirrorFutures.add(future); - future.exceptionally(t2 -> { - logger().error("Failed to mirror message to " + mirrorChannel, t2); + future.exceptionally(t -> { + if (t instanceof CompletionException) { + t = t.getCause(); + } + logger().error("Failed to mirror message to " + describeChannel(mirrorChannel), t); for (InputStream stream : streams) { try { stream.close(); @@ -243,11 +257,22 @@ public class DiscordMessageMirroringModule extends AbstractModule { }); } }).exceptionally(t -> { + if (t instanceof CompletionException) { + t = t.getCause(); + } logger().error("Failed to mirror message", t); return null; }); } + private String describeChannel(DiscordGuildMessageChannel channel) { + if (channel instanceof DiscordThreadChannel) { + return "\"" + channel.getName() + "\" in #" + ((DiscordThreadChannel) channel).getParentChannel().getName(); + } + + return "#" + channel.getName(); + } + @Subscribe public void onDiscordMessageUpdate(DiscordMessageUpdateEvent event) { Cache syncs = mapping.getIfPresent(event.getChannel().getId()); @@ -289,13 +314,13 @@ public class DiscordMessageMirroringModule extends AbstractModule { } for (MessageReference reference : sync.mirrors) { - DiscordMessageChannel channel = reference.getMessageChannel(discordSRV); + DiscordGuildMessageChannel channel = reference.getMessageChannel(discordSRV); if (channel == null) { continue; } channel.deleteMessageById(reference.messageId, reference.webhookMessage).exceptionally(t -> { - logger().error("Failed to delete mirrored message in " + channel); + logger().error("Failed to delete mirrored message in " + describeChannel(channel)); return null; }); }