From 7fa3594c048d9f40008a87e9a749b4854702260a Mon Sep 17 00:00:00 2001 From: cpw Date: Tue, 17 Sep 2019 21:18:33 -0400 Subject: [PATCH] Fixed the problem where an error would cause the main thread to continue even though there were still parallel threads running. Also, handle exceptions in the AutomaticEventSubscriber rather than leaking them to the Parallel processor. Actually closes #6148 Signed-off-by: cpw --- .../java/net/minecraftforge/fml/ModList.java | 16 +++++++++++++++- .../fml/javafmlmod/FMLModContainer.java | 11 ++++++++--- src/main/resources/assets/forge/lang/en_us.json | 1 + 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/minecraftforge/fml/ModList.java b/src/main/java/net/minecraftforge/fml/ModList.java index e19cc35d4..83d350bb7 100644 --- a/src/main/java/net/minecraftforge/fml/ModList.java +++ b/src/main/java/net/minecraftforge/fml/ModList.java @@ -29,6 +29,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Objects; @@ -138,7 +139,14 @@ public class ModList } catch (InterruptedException | ExecutionException e) { - LOGGER.error(LOADING, "Encountered an exception during parallel processing", e); + LOGGER.error(LOADING, "Encountered an exception during parallel processing - sleeping 10 seconds to wait for jobs to finish", e); + errorHandler.accept(Collections.singletonList(new UncaughtModLoadingException(lifecycleEvent.fromStage(), e))); + modLoadingThreadPool.awaitQuiescence(10, TimeUnit.SECONDS); + if (!modLoadingThreadPool.isQuiescent()) { + LOGGER.fatal(LOADING, "The parallel pool has failed to quiesce correctly, forcing a shutdown. There is something really wrong here"); + modLoadingThreadPool.shutdownNow(); + throw new RuntimeException("Forge played \"STOP IT NOW MODS!\" - it was \"NOT VERY EFFECTIVE\""); + } } DeferredWorkQueue.runTasks(lifecycleEvent.fromStage(), errorHandler, executor); FMLLoader.getLanguageLoadingProvider().forEach(lp->lp.consumeLifecycleEvent(()->lifecycleEvent)); @@ -212,4 +220,10 @@ public class ModList public Stream applyForEachModContainer(Function function) { return indexedMods.values().stream().map(function); } + + private static class UncaughtModLoadingException extends ModLoadingException { + public UncaughtModLoadingException(ModLoadingStage stage, Throwable originalException) { + super(null, stage, "fml.modloading.uncaughterror", originalException); + } + } } diff --git a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java index d8b5303bd..ab40bf3af 100644 --- a/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java +++ b/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java @@ -136,9 +136,14 @@ public class FMLModContainer extends ModContainer LOGGER.error(LOADING,"Failed to create mod instance. ModID: {}, class {}", getModId(), modClass.getName(), e); throw new ModLoadingException(modInfo, event.fromStage(), "fml.modloading.failedtoloadmod", e, modClass); } - LOGGER.debug(LOADING, "Injecting Automatic event subscribers for {}", getModId()); - AutomaticEventSubscriber.inject(this, this.scanResults, this.modClass.getClassLoader()); - LOGGER.debug(LOADING, "Completed Automatic event subscribers for {}", getModId()); + try { + LOGGER.debug(LOADING, "Injecting Automatic event subscribers for {}", getModId()); + AutomaticEventSubscriber.inject(this, this.scanResults, this.modClass.getClassLoader()); + LOGGER.debug(LOADING, "Completed Automatic event subscribers for {}", getModId()); + } catch (Throwable e) { + LOGGER.error(LOADING,"Failed to register automatic subscribers. ModID: {}, class {}", getModId(), modClass.getName(), e); + throw new ModLoadingException(modInfo, event.fromStage(), "fml.modloading.failedtoloadmod", e, modClass); + } } @Override diff --git a/src/main/resources/assets/forge/lang/en_us.json b/src/main/resources/assets/forge/lang/en_us.json index 5b04c5838..134964afa 100644 --- a/src/main/resources/assets/forge/lang/en_us.json +++ b/src/main/resources/assets/forge/lang/en_us.json @@ -44,6 +44,7 @@ "fml.modloading.missingmetadata": "mods.toml missing metadata for modid {3}", "fml.modloading.failedtoloadmodclass":"{0,modinfo,name} has class loading errors\n\u00a77{2,exc,msg}", "fml.modloading.failedtoloadmod":"{0,modinfo,name} ({0,modinfo,id}) has failed to load correctly\n\u00a77{2,exc,msg}", + "fml.modloading.uncaughterror":"An uncaught parallel processing error has occurred.\n\u00a77{2,exc,msg}", "fml.modloading.errorduringevent":"{0,modinfo,name} ({0,modinfo,id}) encountered an error during the {1,lower} event phase\n\u00a77{2,exc,msg}", "fml.modloading.failedtoloadforge": "Failed to load forge", "fml.modloading.missingdependency": "Mod \u00a7e{4}\u00a7r requires \u00a76{3}\u00a7r \u00a7o{5,vr}\u00a7r\n\u00a77Currently, \u00a76{3}\u00a7r\u00a77 is \u00a7o{6,i18n,fml.messages.artifactversion.ornotinstalled}",