diff --git a/src/main/java/net/minecraftforge/fml/CrashReportExtender.java b/src/main/java/net/minecraftforge/fml/CrashReportExtender.java index 9d3189f34..632cf526e 100644 --- a/src/main/java/net/minecraftforge/fml/CrashReportExtender.java +++ b/src/main/java/net/minecraftforge/fml/CrashReportExtender.java @@ -23,10 +23,13 @@ import cpw.mods.modlauncher.log.TransformingThrowablePatternConverter; import net.minecraft.crash.CrashReport; import net.minecraft.crash.CrashReportCategory; import net.minecraftforge.fml.common.ICrashCallable; +import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; +import net.minecraftforge.forgespi.language.IModInfo; +import org.apache.logging.log4j.Logger; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.*; import java.util.concurrent.Callable; public class CrashReportExtender @@ -66,4 +69,25 @@ public class CrashReportExtender return TransformingThrowablePatternConverter.generateEnhancedStackTrace(throwable); } + + public static void dumpModLoadingCrashReport(final Logger logger, final LoadingFailedException error, final File topLevelDir) { + final CrashReport crashReport = CrashReport.makeCrashReport(new Exception("Mod Loading has failed"), "Mod loading error has occurred"); + error.getErrors().forEach(mle -> { + final Optional modInfo = Optional.ofNullable(mle.getModInfo()); + final CrashReportCategory category = crashReport.makeCategory(modInfo.map(IModInfo::getModId).orElse("NO MOD INFO AVAILABLE")); + category.applyStackTrace(mle.getCause()); + category.addDetail("Failure message", mle.getCleanMessage()); + category.addDetail("Exception message", Objects.toString(mle.getCause(), "MISSING EXCEPTION MESSAGE")); + category.addDetail("Mod Version", modInfo.map(IModInfo::getVersion).map(Object::toString).orElse("NO MOD INFO AVAILABLE")); + category.addDetail("Mod Issue URL", modInfo.map(IModInfo::getOwningFile).map(ModFileInfo.class::cast).flatMap(mfi->mfi.getConfigElement("issueTrackerURL")).orElse("NOT PROVIDED")); + }); + final File file1 = new File(topLevelDir, "crash-reports"); + final File file2 = new File(file1, "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-fml.txt"); + if (crashReport.saveToFile(file2)) { + logger.fatal("Crash report saved to {}", file2); + } else { + logger.fatal("Failed to save crash report"); + } + System.out.print(crashReport.getCompleteReport()); + } } diff --git a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java index 90e734939..bfeffdf2a 100644 --- a/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java +++ b/src/main/java/net/minecraftforge/fml/client/ClientModLoader.java @@ -24,13 +24,8 @@ import static net.minecraftforge.fml.loading.LogMarkers.LOADING; import java.io.File; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; -import java.util.Objects; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @@ -46,15 +41,7 @@ import net.minecraft.resources.IResourceManager; import net.minecraft.resources.ResourcePackInfo; import net.minecraft.resources.ResourcePackList; import net.minecraft.util.datafix.codec.DatapackCodec; -import net.minecraftforge.fml.BrandingControl; -import net.minecraftforge.fml.LoadingFailedException; -import net.minecraftforge.fml.LogicalSidedProvider; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.fml.ModLoader; -import net.minecraftforge.fml.ModLoadingStage; -import net.minecraftforge.fml.ModLoadingWarning; -import net.minecraftforge.fml.ModWorkManager; -import net.minecraftforge.fml.VersionChecker; +import net.minecraftforge.fml.*; import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -199,23 +186,9 @@ public class ClientModLoader // We can finally start the forge eventbus up MinecraftForge.EVENT_BUS.start(); } else { - final CrashReport crashReport = CrashReport.makeCrashReport(new Exception("Mod Loading has failed"), "Mod loading error has occurred"); - error.getErrors().forEach(mle -> { - final CrashReportCategory category = crashReport.makeCategory(mle.getModInfo().getModId()); - category.applyStackTrace(mle.getCause()); - category.addDetail("Failure message", mle.getCleanMessage()); - category.addDetail("Exception message", mle.getCause().toString()); - category.addDetail("Mod Version", mle.getModInfo().getVersion().toString()); - category.addDetail("Mod Issue URL", ((ModFileInfo)mle.getModInfo().getOwningFile()).getConfigElement("issueTrackerURL").orElse("NOT PROVIDED")); - }); - final File file1 = new File(mc.gameDir, "crash-reports"); - final File file2 = new File(file1, "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-client.txt"); - if (crashReport.saveToFile(file2)) { - LOGGER.fatal("Crash report saved to {}", crashReport.getFile()); - } else { - LOGGER.fatal("Failed to save crash report"); - } - System.out.print(crashReport.getCompleteReport()); + // Double check we have the langs loaded for forge + LanguageHook.loadForgeAndMCLangs(); + CrashReportExtender.dumpModLoadingCrashReport(LOGGER, error, mc.gameDir); } if (error != null || !warnings.isEmpty()) { mc.displayGuiScreen(new LoadingErrorScreen(error, warnings)); diff --git a/src/main/java/net/minecraftforge/fml/server/ServerModLoader.java b/src/main/java/net/minecraftforge/fml/server/ServerModLoader.java index b276fadd0..50f5254e9 100644 --- a/src/main/java/net/minecraftforge/fml/server/ServerModLoader.java +++ b/src/main/java/net/minecraftforge/fml/server/ServerModLoader.java @@ -22,11 +22,7 @@ package net.minecraftforge.fml.server; import net.minecraft.crash.CrashReport; import net.minecraft.crash.CrashReportCategory; import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.LoadingFailedException; -import net.minecraftforge.fml.LogicalSidedProvider; -import net.minecraftforge.fml.ModLoader; -import net.minecraftforge.fml.ModLoadingWarning; -import net.minecraftforge.fml.ModWorkManager; +import net.minecraftforge.fml.*; import net.minecraftforge.fml.loading.moddiscovery.ModFileInfo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -55,23 +51,9 @@ public class ServerModLoader ModLoader.get().finishMods(ModWorkManager.syncExecutor(), ModWorkManager.parallelExecutor(), ()->{}); } catch (LoadingFailedException error) { ServerModLoader.hasErrors = true; - final CrashReport crashReport = CrashReport.makeCrashReport(error, "Mod loading error has occurred"); - error.getErrors().forEach(mle -> { - final CrashReportCategory category = crashReport.makeCategory(mle.getModInfo().getModId()); - category.applyStackTrace(mle.getCause()); - category.addDetail("Failure message", mle.getCleanMessage()); - category.addDetail("Exception message", mle.getCause().toString()); - category.addDetail("Mod Version", mle.getModInfo().getVersion().toString()); - category.addDetail("Mod Issue URL", ((ModFileInfo)mle.getModInfo().getOwningFile()).getConfigElement("issueTrackerURL").orElse("NOT PROVIDED")); - }); - final File file1 = new File("crash-reports"); - final File file2 = new File(file1, "crash-" + (new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss")).format(new Date()) + "-server.txt"); - if (crashReport.saveToFile(file2)) { - LOGGER.fatal("Crash report saved to {}", file2); - } else { - LOGGER.fatal("Failed to save crash report"); - } - System.out.print(crashReport.getCompleteReport()); + // In case its not loaded properly + LanguageHook.loadForgeAndMCLangs(); + CrashReportExtender.dumpModLoadingCrashReport(LOGGER, error, new File(".")); throw error; } List warnings = ModLoader.get().getWarnings();