add exception printing by default to all futures

This commit is contained in:
Pyrbu 2024-12-18 07:08:46 +01:00
parent e30d6a5782
commit e621ac6908
8 changed files with 40 additions and 13 deletions

View file

@ -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;

View file

@ -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));
});

View file

@ -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));
});

View file

@ -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<Void> 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) {

View file

@ -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<SkinImpl> 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 {

View file

@ -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<PrefetchedDescriptor> 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<PrefetchedDescriptor> 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

View file

@ -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<Void> allOf(Collection<CompletableFuture<?>> futures) {
return CompletableFuture.runAsync(() -> {
return exceptionPrintingRunAsync(() -> {
for (CompletableFuture<?> future : futures) future.join();
});
}
public static <T> CompletableFuture<T> newExceptionPrintingFuture() {
return new CompletableFuture<T>().exceptionally(throwable -> {
throwable.printStackTrace();
return null;
});
}
public static CompletableFuture<Void> exceptionPrintingRunAsync(Runnable runnable) {
return CompletableFuture.runAsync(runnable).exceptionally(throwable -> {
throwable.printStackTrace();
return null;
});
}
public static <T> CompletableFuture<T> exceptionPrintingSupplyAsync(Supplier<T> supplier) {
return CompletableFuture.supplyAsync(supplier).exceptionally(throwable -> {
throwable.printStackTrace();
return null;
});
}
}

View file

@ -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) {