From e621ac69085cd5fe500e812f6090e977b523fbb8 Mon Sep 17 00:00:00 2001 From: Pyrbu Date: Wed, 18 Dec 2024 07:08:46 +0100 Subject: [PATCH] add exception printing by default to all futures --- .../commands/storage/ImportCommand.java | 4 ++-- .../commands/storage/LoadAllCommand.java | 3 ++- .../commands/storage/SaveAllCommand.java | 3 ++- .../pyr/znpcsplus/entity/PacketEntity.java | 3 ++- .../znpcsplus/skin/cache/MojangSkinCache.java | 9 +++---- .../skin/descriptor/PrefetchedDescriptor.java | 5 ++-- .../lol/pyr/znpcsplus/util/FutureUtil.java | 24 ++++++++++++++++++- .../java/lol/pyr/znpcsplus/util/Viewable.java | 2 +- 8 files changed, 40 insertions(+), 13 deletions(-) diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/ImportCommand.java b/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/ImportCommand.java index 39b492c..c6c598e 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/ImportCommand.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/ImportCommand.java @@ -7,13 +7,13 @@ import lol.pyr.znpcsplus.conversion.DataImporter; import lol.pyr.znpcsplus.conversion.DataImporterRegistry; import lol.pyr.znpcsplus.npc.NpcEntryImpl; import lol.pyr.znpcsplus.npc.NpcRegistryImpl; +import lol.pyr.znpcsplus.util.FutureUtil; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.concurrent.CompletableFuture; public class ImportCommand implements CommandHandler { private final NpcRegistryImpl npcRegistry; @@ -33,7 +33,7 @@ public class ImportCommand implements CommandHandler { if (importer == null) context.halt(Component.text("Importer not found! Possible importers: " + String.join(", ", importerRegistry.getIds()), NamedTextColor.RED)); - CompletableFuture.runAsync(() -> { + FutureUtil.exceptionPrintingRunAsync(() -> { if (!importer.isValid()) { context.send(Component.text("There is no data to import from this importer!", NamedTextColor.RED)); return; diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/LoadAllCommand.java b/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/LoadAllCommand.java index 1402816..e007656 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/LoadAllCommand.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/LoadAllCommand.java @@ -4,6 +4,7 @@ import lol.pyr.director.adventure.command.CommandContext; import lol.pyr.director.adventure.command.CommandHandler; import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.znpcsplus.npc.NpcRegistryImpl; +import lol.pyr.znpcsplus.util.FutureUtil; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -20,7 +21,7 @@ public class LoadAllCommand implements CommandHandler { @Override public void run(CommandContext context) throws CommandExecutionException { - CompletableFuture.runAsync(() -> { + FutureUtil.exceptionPrintingRunAsync(() -> { npcRegistry.reload(); context.send(Component.text("All NPCs have been re-loaded from storage", NamedTextColor.GREEN)); }); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/SaveAllCommand.java b/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/SaveAllCommand.java index d995f30..4188a38 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/SaveAllCommand.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/commands/storage/SaveAllCommand.java @@ -4,6 +4,7 @@ import lol.pyr.director.adventure.command.CommandContext; import lol.pyr.director.adventure.command.CommandHandler; import lol.pyr.director.common.command.CommandExecutionException; import lol.pyr.znpcsplus.npc.NpcRegistryImpl; +import lol.pyr.znpcsplus.util.FutureUtil; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -20,7 +21,7 @@ public class SaveAllCommand implements CommandHandler { @Override public void run(CommandContext context) throws CommandExecutionException { - CompletableFuture.runAsync(() -> { + FutureUtil.exceptionPrintingRunAsync(() -> { npcRegistry.save(); context.send(Component.text("All NPCs have been saved to storage", NamedTextColor.GREEN)); }); diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/entity/PacketEntity.java b/plugin/src/main/java/lol/pyr/znpcsplus/entity/PacketEntity.java index a46c9d4..4e51020 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/entity/PacketEntity.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/entity/PacketEntity.java @@ -8,6 +8,7 @@ import lol.pyr.znpcsplus.api.entity.EntityProperty; import lol.pyr.znpcsplus.api.entity.PropertyHolder; import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.reflection.Reflections; +import lol.pyr.znpcsplus.util.FutureUtil; import lol.pyr.znpcsplus.util.NpcLocation; import lol.pyr.znpcsplus.util.Viewable; import org.bukkit.entity.Player; @@ -67,7 +68,7 @@ public class PacketEntity implements PropertyHolder { } public CompletableFuture spawn(Player player) { - return CompletableFuture.runAsync(() -> { + return FutureUtil.exceptionPrintingRunAsync(() -> { if (type == EntityTypes.PLAYER) packetFactory.spawnPlayer(player, this, properties).join(); else packetFactory.spawnEntity(player, this, properties); if (vehicleId != null) { diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/skin/cache/MojangSkinCache.java b/plugin/src/main/java/lol/pyr/znpcsplus/skin/cache/MojangSkinCache.java index 2a54509..3b0a982 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/skin/cache/MojangSkinCache.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/skin/cache/MojangSkinCache.java @@ -5,6 +5,7 @@ import com.google.gson.JsonParser; import lol.pyr.znpcsplus.config.ConfigManager; import lol.pyr.znpcsplus.reflection.Reflections; import lol.pyr.znpcsplus.skin.SkinImpl; +import lol.pyr.znpcsplus.util.FutureUtil; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -42,7 +43,7 @@ public class MojangSkinCache { if (idCache.containsKey(name.toLowerCase())) return fetchByUUID(idCache.get(name.toLowerCase()).getId()); - return CompletableFuture.supplyAsync(() -> { + return FutureUtil.exceptionPrintingSupplyAsync(() -> { URL url = parseUrl("https://api.mojang.com/users/profiles/minecraft/" + name); HttpURLConnection connection = null; try { @@ -75,7 +76,7 @@ public class MojangSkinCache { if (idCache.containsKey(name.toLowerCase())) return fetchByUUID(idCache.get(name.toLowerCase()).getId()); - return CompletableFuture.supplyAsync(() -> { + return FutureUtil.exceptionPrintingSupplyAsync(() -> { URL url = parseUrl("https://api.ashcon.app/mojang/v2/user/" + name); HttpURLConnection connection = null; try { @@ -106,7 +107,7 @@ public class MojangSkinCache { } public CompletableFuture fetchByUrl(URL url, String variant) { - return CompletableFuture.supplyAsync(() -> { + return FutureUtil.exceptionPrintingSupplyAsync(() -> { URL apiUrl = parseUrl("https://api.mineskin.org/generate/url"); HttpURLConnection connection = null; try { @@ -170,7 +171,7 @@ public class MojangSkinCache { if (!skin.isExpired()) return CompletableFuture.completedFuture(skin); } - return CompletableFuture.supplyAsync(() -> { + return FutureUtil.exceptionPrintingSupplyAsync(() -> { URL url = parseUrl("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid + "?unsigned=false"); HttpURLConnection connection = null; try { diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/PrefetchedDescriptor.java b/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/PrefetchedDescriptor.java index c852080..3e62802 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/PrefetchedDescriptor.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/skin/descriptor/PrefetchedDescriptor.java @@ -5,6 +5,7 @@ import lol.pyr.znpcsplus.api.skin.SkinDescriptor; import lol.pyr.znpcsplus.skin.BaseSkinDescriptor; import lol.pyr.znpcsplus.skin.SkinImpl; import lol.pyr.znpcsplus.skin.cache.MojangSkinCache; +import lol.pyr.znpcsplus.util.FutureUtil; import org.bukkit.entity.Player; import java.net.URL; @@ -18,11 +19,11 @@ public class PrefetchedDescriptor implements BaseSkinDescriptor, SkinDescriptor } public static CompletableFuture forPlayer(MojangSkinCache cache, String name) { - return CompletableFuture.supplyAsync(() -> new PrefetchedDescriptor(cache.fetchByName(name).join())); + return FutureUtil.exceptionPrintingSupplyAsync(() -> new PrefetchedDescriptor(cache.fetchByName(name).join())); } public static CompletableFuture fromUrl(MojangSkinCache cache, URL url, String variant) { - return CompletableFuture.supplyAsync(() -> new PrefetchedDescriptor(cache.fetchByUrl(url, variant).join())); + return FutureUtil.exceptionPrintingSupplyAsync(() -> new PrefetchedDescriptor(cache.fetchByUrl(url, variant).join())); } @Override diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/util/FutureUtil.java b/plugin/src/main/java/lol/pyr/znpcsplus/util/FutureUtil.java index 3b0c31c..18ca6e4 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/util/FutureUtil.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/util/FutureUtil.java @@ -2,11 +2,33 @@ package lol.pyr.znpcsplus.util; import java.util.Collection; import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; public class FutureUtil { public static CompletableFuture allOf(Collection> futures) { - return CompletableFuture.runAsync(() -> { + return exceptionPrintingRunAsync(() -> { for (CompletableFuture future : futures) future.join(); }); } + + public static CompletableFuture newExceptionPrintingFuture() { + return new CompletableFuture().exceptionally(throwable -> { + throwable.printStackTrace(); + return null; + }); + } + + public static CompletableFuture exceptionPrintingRunAsync(Runnable runnable) { + return CompletableFuture.runAsync(runnable).exceptionally(throwable -> { + throwable.printStackTrace(); + return null; + }); + } + + public static CompletableFuture exceptionPrintingSupplyAsync(Supplier supplier) { + return CompletableFuture.supplyAsync(supplier).exceptionally(throwable -> { + throwable.printStackTrace(); + return null; + }); + } } diff --git a/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java b/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java index 19637d8..9dd4160 100644 --- a/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java +++ b/plugin/src/main/java/lol/pyr/znpcsplus/util/Viewable.java @@ -30,7 +30,7 @@ public abstract class Viewable { private void tryRunQueue() { if (visibilityTaskQueue.isEmpty() || queueRunning) return; queueRunning = true; - CompletableFuture.runAsync(() -> { + FutureUtil.exceptionPrintingRunAsync(() -> { while (!visibilityTaskQueue.isEmpty()) try { visibilityTaskQueue.remove().run(); } catch (Exception e) {