diff --git a/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java b/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java index a2fbedbe1c..e0186a00bc 100644 --- a/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java +++ b/javafmllanguage/src/main/java/net/minecraftforge/fml/javafmlmod/FMLModContainer.java @@ -21,6 +21,8 @@ import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; +import java.lang.reflect.InvocationTargetException; +import java.util.Objects; import java.util.Optional; public class FMLModContainer extends ModContainer @@ -70,6 +72,11 @@ public class FMLModContainer extends ModContainer } catch (Throwable e) { + // When a mod constructor throws an exception, it's wrapped in an InvocationTargetException which hides the + // actual exception from the mod loading error screen. + if (e instanceof InvocationTargetException wrapped) + e = Objects.requireNonNullElse(wrapped.getCause(), e); // unwrap the exception + LOGGER.error(LOADING,"Failed to create mod instance. ModID: {}, class {}", getModId(), modClass.getName(), e); throw new ModLoadingException(modInfo, ModLoadingStage.CONSTRUCT, "fml.modloading.failedtoloadmod", e, modClass); } diff --git a/src/test/java/net/minecraftforge/debug/ConstructorThrowTest.java b/src/test/java/net/minecraftforge/debug/ConstructorThrowTest.java new file mode 100644 index 0000000000..b3cd624923 --- /dev/null +++ b/src/test/java/net/minecraftforge/debug/ConstructorThrowTest.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) Forge Development LLC and contributors + * SPDX-License-Identifier: LGPL-2.1-only + */ + +package net.minecraftforge.debug; + +import net.minecraftforge.fml.common.Mod; + +/** + * Test that the mod loading error screen shows the cause of the crash when a mod constructor throws an exception. + *

Enable or disable this test in the mods.toml

+ */ +@Mod("constructor_throw_test") +public class ConstructorThrowTest { + public ConstructorThrowTest() { + throw new RuntimeException("Test"); + } +} diff --git a/src/test/resources/META-INF/mods.toml b/src/test/resources/META-INF/mods.toml index a9fa2b1b23..c616f287ac 100644 --- a/src/test/resources/META-INF/mods.toml +++ b/src/test/resources/META-INF/mods.toml @@ -33,6 +33,9 @@ modId="mdk_datagen" [[mods]] modId="custom_preset_editor_test" +#[[mods]] +# modId="constructor_throw_test" + # LEGACY TEST CASES ###### The mods below are from the old test framework and need to be yeeted later again.