diff --git a/src/main/java/net/minecraftforge/fml/common/LoadController.java b/src/main/java/net/minecraftforge/fml/common/LoadController.java index 0876732725..b6ed0b8bd7 100644 --- a/src/main/java/net/minecraftforge/fml/common/LoadController.java +++ b/src/main/java/net/minecraftforge/fml/common/LoadController.java @@ -159,52 +159,70 @@ public class LoadController LoaderState oldState = state; state = state.transition(!errors.isEmpty()); - if (state != desiredState && !forceState) + if (state != desiredState) { - Entry toThrow = null; - FMLLog.log.fatal("Fatal errors were detected during the transition from {} to {}. Loading cannot continue", oldState, desiredState); - StringBuilder sb = new StringBuilder(); - printModStates(sb); - FMLLog.log.fatal(sb.toString()); - if (errors.size()>0) + if (!forceState) { - FMLLog.log.fatal("The following problems were captured during this phase"); - for (Entry error : errors.entries()) - { - String modId = error.getKey(); - String modName = modNames.get(modId); - FMLLog.log.error("Caught exception from {} ({})", modId, error.getValue()); - if (error.getValue() instanceof IFMLHandledException) - { - toThrow = error; - } - else if (toThrow == null) - { - toThrow = error; - } - } + FMLLog.log.fatal("Fatal errors were detected during the transition from {} to {}. Loading cannot continue", oldState, desiredState); + throw throwStoredErrors(); } else { - FMLLog.log.fatal("The ForgeModLoader state engine has become corrupted. Probably, a state was missed by and invalid modification to a base class" + - "ForgeModLoader depends on. This is a critical error and not recoverable. Investigate any modifications to base classes outside of" + - "ForgeModLoader, especially Optifine, to see if there are fixes available."); - throw new RuntimeException("The ForgeModLoader state engine is invalid"); - } - if (toThrow != null) - { - String modId = toThrow.getKey(); - String modName = modNames.get(modId); - String errMsg = String.format("Caught exception from %s (%s)", modName, modId); - throw new LoaderExceptionModCrash(errMsg, toThrow.getValue()); + FMLLog.log.info("The state engine was in incorrect state {} and forced into state {}. Errors may have been discarded.", state, desiredState); + forceState(desiredState); } } - else if (state != desiredState && forceState) + } + + public void checkErrorsAfterAvailable() + { + if (errors.size() > 0) { - FMLLog.log.info("The state engine was in incorrect state {} and forced into state {}. Errors may have been discarded.", state, desiredState); - forceState(desiredState); + FMLLog.log.fatal("Fatal errors were detected during {}. Loading cannot continue", LoaderState.AVAILABLE); + throw throwStoredErrors(); + } + } + + private RuntimeException throwStoredErrors() + { + Entry toThrow = null; + StringBuilder sb = new StringBuilder(); + printModStates(sb); + FMLLog.log.fatal(sb.toString()); + if (errors.size() > 0) + { + FMLLog.log.fatal("The following problems were captured during this phase"); + for (Entry entry : errors.entries()) + { + String modId = entry.getKey(); + String modName = modNames.get(modId); + Throwable error = entry.getValue(); + FMLLog.log.error("Caught exception from {} ({})", modId, modName, error); + if (error instanceof IFMLHandledException) + { + toThrow = entry; + } + else if (toThrow == null) + { + toThrow = entry; + } + } } + if (toThrow == null) + { + FMLLog.log.fatal("The ForgeModLoader state engine has become corrupted. Probably, a state was missed by and invalid modification to a base class" + + "ForgeModLoader depends on. This is a critical error and not recoverable. Investigate any modifications to base classes outside of" + + "ForgeModLoader, especially Optifine, to see if there are fixes available."); + throw new RuntimeException("The ForgeModLoader state engine is invalid"); + } + else + { + String modId = toThrow.getKey(); + String modName = modNames.get(modId); + String errMsg = String.format("Caught exception from %s (%s)", modName, modId); + throw new LoaderExceptionModCrash(errMsg, toThrow.getValue()); + } } @Nullable diff --git a/src/main/java/net/minecraftforge/fml/common/Loader.java b/src/main/java/net/minecraftforge/fml/common/Loader.java index d38e7c1d59..f76b4b54c4 100644 --- a/src/main/java/net/minecraftforge/fml/common/Loader.java +++ b/src/main/java/net/minecraftforge/fml/common/Loader.java @@ -725,6 +725,7 @@ public class Loader progressBar.step("Finishing up"); modController.transition(LoaderState.AVAILABLE, false); modController.distributeStateMessage(LoaderState.AVAILABLE); + modController.checkErrorsAfterAvailable(); GameData.freezeData(); FMLLog.log.info("Forge Mod Loader has successfully loaded {} mod{}", mods.size(), mods.size() == 1 ? "" : "s"); progressBar.step("Completing Minecraft initialization"); diff --git a/src/test/java/net/minecraftforge/debug/ClientExceptionTestMod.java b/src/test/java/net/minecraftforge/debug/ClientExceptionTestMod.java index b45e2046b8..e07abde23a 100644 --- a/src/test/java/net/minecraftforge/debug/ClientExceptionTestMod.java +++ b/src/test/java/net/minecraftforge/debug/ClientExceptionTestMod.java @@ -5,6 +5,7 @@ import net.minecraft.client.gui.GuiErrorScreen; import net.minecraftforge.fml.client.CustomModLoadingErrorDisplayException; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLLoadCompleteEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; @Mod(modid = "clientexceptiontest", version = "1.0", name = "Client Exception Test", clientSideOnly = true) @@ -12,8 +13,9 @@ public class ClientExceptionTestMod { // Disabled so other test mods can still work. - public static boolean ENABLE_PREINIT = false, ENABLE_INIT = false; - private static String LOREM_IPSUM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."; + public static boolean ENABLE_PREINIT = false; + public static boolean ENABLE_INIT = false; + public static boolean ENABLE_LOAD_COMPLETE = false; @Mod.EventHandler public void onPreInit(FMLPreInitializationEvent e) @@ -33,6 +35,15 @@ public class ClientExceptionTestMod } } + @Mod.EventHandler + public void onLoadComplete(FMLLoadCompleteEvent e) + { + if (ENABLE_LOAD_COMPLETE) + { + throwException("Thrown in load complete"); + } + } + private void throwException(String runtimeMessage) { throw new CustomModLoadingErrorDisplayException("Custom Test Exception", new RuntimeException(runtimeMessage)) @@ -44,7 +55,7 @@ public class ClientExceptionTestMod public void drawScreen(GuiErrorScreen parent, FontRenderer fontRenderer, int mouseRelX, int mouseRelY, float tickTime) { parent.drawCenteredString(parent.mc.fontRenderer, "Custom Test Exception", parent.width / 2, 90, 16777215); - parent.drawCenteredString(parent.mc.fontRenderer, LOREM_IPSUM, parent.width / 2, 110, 16777215); + parent.drawCenteredString(parent.mc.fontRenderer, runtimeMessage, parent.width / 2, 110, 16777215); } }; }