diff --git a/src/main/java/net/minecraftforge/fml/common/LoadController.java b/src/main/java/net/minecraftforge/fml/common/LoadController.java index 7422eec03..d5859bf52 100644 --- a/src/main/java/net/minecraftforge/fml/common/LoadController.java +++ b/src/main/java/net/minecraftforge/fml/common/LoadController.java @@ -23,6 +23,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.Collection; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Map.Entry; import net.minecraftforge.fml.common.LoaderState.ModState; @@ -62,6 +63,7 @@ public class LoadController private LoaderState state; private Multimap modStates = ArrayListMultimap.create(); private Multimap errors = ArrayListMultimap.create(); + private Map modNames = Maps.newHashMap(); private List activeModList = Lists.newArrayList(); private ModContainer activeContainer; private BiMap modObjectList; @@ -130,6 +132,7 @@ public class LoadController modStates.put(mod.getModId(), ModState.UNLOADED); modStates.put(mod.getModId(), ModState.DISABLED); } + modNames.put(mod.getModId(), mod.getName()); } eventChannels = eventBus.build(); @@ -149,7 +152,7 @@ public class LoadController state = state.transition(!errors.isEmpty()); if (state != desiredState && !forceState) { - Throwable toThrow = null; + Entry toThrow = null; FMLLog.severe("Fatal errors were detected during the transition from %s to %s. Loading cannot continue", oldState, desiredState); StringBuilder sb = new StringBuilder(); printModStates(sb); @@ -159,14 +162,16 @@ public class LoadController FMLLog.severe("The following problems were captured during this phase"); for (Entry error : errors.entries()) { - FMLLog.log(Level.ERROR, error.getValue(), "Caught exception from %s", error.getKey()); + String modId = error.getKey(); + String modName = modNames.get(modId); + FMLLog.log(Level.ERROR, error.getValue(), "Caught exception from %s (%s)", modName, modId); if (error.getValue() instanceof IFMLHandledException) { - toThrow = error.getValue(); + toThrow = error; } else if (toThrow == null) { - toThrow = error.getValue(); + toThrow = error; } } } @@ -177,13 +182,12 @@ public class LoadController "ForgeModLoader, especially Optifine, to see if there are fixes available."); throw new RuntimeException("The ForgeModLoader state engine is invalid"); } - if (toThrow != null && toThrow instanceof RuntimeException) + if (toThrow != null) { - throw (RuntimeException)toThrow; - } - else - { - throw new LoaderException(toThrow); + 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()); } } else if (state != desiredState && forceState) diff --git a/src/main/java/net/minecraftforge/fml/common/LoaderException.java b/src/main/java/net/minecraftforge/fml/common/LoaderException.java index befa726a8..f6b7436fd 100644 --- a/src/main/java/net/minecraftforge/fml/common/LoaderException.java +++ b/src/main/java/net/minecraftforge/fml/common/LoaderException.java @@ -38,6 +38,10 @@ public class LoaderException extends EnhancedRuntimeException { super(message); } + public LoaderException(String message, Throwable cause) + { + super(message, cause); + } @Override protected void printStackTrace(WrappedPrintStream stream){} } diff --git a/src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java b/src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java new file mode 100644 index 000000000..a41fe589c --- /dev/null +++ b/src/main/java/net/minecraftforge/fml/common/LoaderExceptionModCrash.java @@ -0,0 +1,39 @@ +/* + * Minecraft Forge + * Copyright (c) 2016. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.fml.common; + +/** + * Prevent LoaderException from adding its own stack trace to the wrapped throwable's stack trace. + */ +public class LoaderExceptionModCrash extends LoaderException +{ + private static final long serialVersionUID = 1L; + + public LoaderExceptionModCrash(String message, Throwable cause) + { + super(message, cause); + } + + @Override + public synchronized Throwable fillInStackTrace() + { + return this; + } +}