diff --git a/src/main/java/dan200/computercraft/ComputerCraft.java b/src/main/java/dan200/computercraft/ComputerCraft.java index 210af293e..75280d0b8 100644 --- a/src/main/java/dan200/computercraft/ComputerCraft.java +++ b/src/main/java/dan200/computercraft/ComputerCraft.java @@ -68,6 +68,7 @@ import net.minecraftforge.fml.common.network.FMLEventChannel; import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraftforge.fml.common.network.internal.FMLProxyPacket; import net.minecraftforge.fml.relauncher.Side; +import org.apache.logging.log4j.Logger; import java.io.File; import java.io.IOException; @@ -106,6 +107,7 @@ public class ComputerCraft public static String http_whitelist = "*"; public static boolean disable_lua51_features = false; public static String default_computer_settings = ""; + public static boolean logPeripheralErrors = false; public static boolean enableCommandBlock = false; public static boolean turtlesNeedFuel = true; @@ -179,6 +181,7 @@ public class ComputerCraft public static Property http_whitelist; public static Property disable_lua51_features; public static Property default_computer_settings; + public static Property logPeripheralErrors; public static Property enableCommandBlock; public static Property turtlesNeedFuel; @@ -207,6 +210,9 @@ public class ComputerCraft // Creative public static CreativeTabMain mainCreativeTab; + // Logging + public static Logger log; + // API users private static List peripheralProviders = new ArrayList(); private static List bundledRedstoneProviders = new ArrayList(); @@ -231,6 +237,8 @@ public class ComputerCraft @Mod.EventHandler public void preInit( FMLPreInitializationEvent event ) { + log = event.getModLog(); + // Load config Config.config = new Configuration( event.getSuggestedConfigurationFile() ); Config.config.load(); @@ -247,6 +255,10 @@ public class ComputerCraft Config.default_computer_settings = Config.config.get( Configuration.CATEGORY_GENERAL, "default_computer_settings", default_computer_settings ); Config.default_computer_settings.setComment( "A comma seperated list of default system settings to set on new computers. Example: \"shell.autocomplete=false,lua.autocomplete=false,edit.autocomplete=false\" will disable all autocompletion" ); + Config.logPeripheralErrors = Config.config.get( Configuration.CATEGORY_GENERAL, "logPeripheralErrors", logPeripheralErrors ); + Config.logPeripheralErrors.setComment( "Log exceptions thrown by peripherals and other Lua objects.\n" + + "This makes it easier for mod authors to debug problems, but may result in log spam should people use buggy methods." ); + Config.enableCommandBlock = Config.config.get( Configuration.CATEGORY_GENERAL, "enableCommandBlock", enableCommandBlock ); Config.enableCommandBlock.setComment( "Enable Command Block peripheral support" ); @@ -605,7 +617,7 @@ public class ComputerCraft } catch( Exception e ) { - // mod misbehaved, ignore it + ComputerCraft.log.error( "Peripheral provider " + peripheralProvider + " errored.", e ); } } return null; @@ -649,7 +661,7 @@ public class ComputerCraft } catch( Exception e ) { - // mod misbehaved, ignore it + ComputerCraft.log.error( "Bundled redstone provider " + bundledRedstoneProvider + " errored.", e ); } } return combinedSignal; @@ -673,6 +685,7 @@ public class ComputerCraft catch( Exception e ) { // mod misbehaved, ignore it + ComputerCraft.log.error( "Media provider " + mediaProvider + " errored.", e ); } } return null; diff --git a/src/main/java/dan200/computercraft/core/computer/Computer.java b/src/main/java/dan200/computercraft/core/computer/Computer.java index 712979521..885f85188 100644 --- a/src/main/java/dan200/computercraft/core/computer/Computer.java +++ b/src/main/java/dan200/computercraft/core/computer/Computer.java @@ -469,7 +469,7 @@ public class Computer } catch( FileSystemException e ) { - e.printStackTrace(); + ComputerCraft.log.error( "Cannot mount rom", e ); return false; } } diff --git a/src/main/java/dan200/computercraft/core/computer/ComputerThread.java b/src/main/java/dan200/computercraft/core/computer/ComputerThread.java index 1915c5afb..f84a2e5c8 100644 --- a/src/main/java/dan200/computercraft/core/computer/ComputerThread.java +++ b/src/main/java/dan200/computercraft/core/computer/ComputerThread.java @@ -6,6 +6,8 @@ package dan200.computercraft.core.computer; +import dan200.computercraft.ComputerCraft; + import java.util.ArrayList; import java.util.Iterator; import java.util.WeakHashMap; @@ -106,8 +108,7 @@ public class ComputerThread try { task.execute(); } catch( Throwable e ) { - System.out.println( "ComputerCraft: Error running task." ); - e.printStackTrace(); + ComputerCraft.log.error( "Error running task", e ); } } } ); @@ -139,7 +140,7 @@ public class ComputerThread // Step 3: abandon if( worker.isAlive() ) { - //System.out.println( "computercraft: Warning! Failed to abort Computer " + computercraft.getDescription() + ". Dangling lua thread could cause errors." ); + // ComputerCraft.log.warn( "Failed to abort Computer " + computer.getID() + ". Dangling lua thread could cause errors." ); worker.interrupt(); } } diff --git a/src/main/java/dan200/computercraft/core/lua/LuaJLuaMachine.java b/src/main/java/dan200/computercraft/core/lua/LuaJLuaMachine.java index 933ca3291..574aed974 100644 --- a/src/main/java/dan200/computercraft/core/lua/LuaJLuaMachine.java +++ b/src/main/java/dan200/computercraft/core/lua/LuaJLuaMachine.java @@ -15,6 +15,7 @@ import dan200.computercraft.core.apis.ILuaAPI; import dan200.computercraft.core.computer.Computer; import dan200.computercraft.core.computer.ITask; import dan200.computercraft.core.computer.MainThread; + import org.luaj.vm2.*; import org.luaj.vm2.lib.OneArgFunction; import org.luaj.vm2.lib.VarArgFunction; @@ -183,6 +184,7 @@ public class LuaJLuaMachine implements ILuaMachine } catch( LuaError e ) { + ComputerCraft.log.warn( "Could not load bios.lua ", e ); if( m_mainRoutine != null ) { ((LuaThread)m_mainRoutine).abandon(); @@ -327,7 +329,8 @@ public class LuaJLuaMachine implements ILuaMachine { final int method = i; final ILuaObject apiObject = object; - table.set( methods[i], new VarArgFunction() { + final String methodName = methods[i]; + table.set( methodName, new VarArgFunction() { @Override public Varargs invoke( Varargs _args ) { @@ -412,6 +415,10 @@ public class LuaJLuaMachine implements ILuaMachine } catch( Throwable t ) { + if( ComputerCraft.logPeripheralErrors ) + { + ComputerCraft.log.error( "Error running task", t ); + } m_computer.queueEvent( "task_complete", new Object[] { taskID, false, "Java Exception Thrown: " + t.toString() } ); @@ -478,6 +485,10 @@ public class LuaJLuaMachine implements ILuaMachine } catch( Throwable t ) { + if( ComputerCraft.logPeripheralErrors ) + { + ComputerCraft.log.error( "Error calling " + methodName + " on " + apiObject, t ); + } throw new LuaError( "Java Exception Thrown: " + t.toString(), 0 ); } return LuaValue.varargsOf( toValues( results, 0 ) ); diff --git a/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java b/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java index ce7f23e48..fa708a193 100644 --- a/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java +++ b/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java @@ -7,6 +7,7 @@ package dan200.computercraft.shared.computer.apis; import com.google.common.collect.ImmutableMap; +import dan200.computercraft.ComputerCraft; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.ILuaTask; import dan200.computercraft.api.lua.LuaException; @@ -98,6 +99,10 @@ public class CommandAPI implements ILuaAPI } catch( Throwable t ) { + if( ComputerCraft.logPeripheralErrors ) + { + ComputerCraft.log.error( "Error running command.", t ); + } return new Object[]{ false, createOutput( "Java Exception Thrown: " + t.toString() ) }; } } @@ -208,6 +213,10 @@ public class CommandAPI implements ILuaAPI catch( Throwable t ) { // Ignore buggy command + if( ComputerCraft.logPeripheralErrors ) + { + ComputerCraft.log.error( "Error checking permissions of command.", t ); + } } } } diff --git a/src/main/java/dan200/computercraft/shared/network/PacketHandler.java b/src/main/java/dan200/computercraft/shared/network/PacketHandler.java index 9db6d7717..64c669794 100644 --- a/src/main/java/dan200/computercraft/shared/network/PacketHandler.java +++ b/src/main/java/dan200/computercraft/shared/network/PacketHandler.java @@ -24,7 +24,7 @@ public class PacketHandler } catch( Exception e ) { - e.printStackTrace(); + ComputerCraft.log.error( "Error handling packet", e ); } } @@ -39,7 +39,7 @@ public class PacketHandler } catch( Exception e ) { - e.printStackTrace(); + ComputerCraft.log.error( "Error handling packet", e ); } } } diff --git a/src/main/java/dan200/computercraft/shared/proxy/CCTurtleProxyCommon.java b/src/main/java/dan200/computercraft/shared/proxy/CCTurtleProxyCommon.java index 5e8aa8d76..da0df9e33 100644 --- a/src/main/java/dan200/computercraft/shared/proxy/CCTurtleProxyCommon.java +++ b/src/main/java/dan200/computercraft/shared/proxy/CCTurtleProxyCommon.java @@ -82,7 +82,9 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy int id = upgrade.getLegacyUpgradeID(); if( id >= 0 && id < 64 ) { - throw new RuntimeException( "Error registering '"+upgrade.getUnlocalisedAdjective()+" Turtle'. Legacy UpgradeID '"+id+"' is reserved by ComputerCraft" ); + String message = "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. Legacy UpgradeID '" + id + "' is reserved by ComputerCraft"; + ComputerCraft.log.error( message ); + throw new RuntimeException( message ); } // Register @@ -116,6 +118,7 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy } catch( Exception e ) { + ComputerCraft.log.error("Error getting computer upgrade item", e); } } return null; @@ -224,13 +227,17 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy { if( legacyID >= Short.MAX_VALUE ) { - throw new RuntimeException( "Error registering '"+upgrade.getUnlocalisedAdjective()+" Turtle'. UpgradeID '"+legacyID+"' is out of range" ); + String message = "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. UpgradeID '" + legacyID + "' is out of range"; + ComputerCraft.log.error( message ); + throw new RuntimeException( message ); } ITurtleUpgrade existing = m_legacyTurtleUpgrades.get( legacyID ); if( existing != null ) { - throw new RuntimeException( "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. UpgradeID '" + legacyID + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" ); + String message = "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. UpgradeID '" + legacyID + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'"; + ComputerCraft.log.error( message ); + throw new RuntimeException( message ); } } @@ -238,7 +245,9 @@ public abstract class CCTurtleProxyCommon implements ICCTurtleProxy ITurtleUpgrade existing = m_turtleUpgrades.get( id ); if( existing != null ) { - throw new RuntimeException( "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. UpgradeID '" + id + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'" ); + String message = "Error registering '" + upgrade.getUnlocalisedAdjective() + " Turtle'. UpgradeID '" + id + "' is already registered by '" + existing.getUnlocalisedAdjective() + " Turtle'"; + ComputerCraft.log.error( message ); + throw new RuntimeException( message ); } // Register diff --git a/src/main/java/dan200/computercraft/shared/util/IDAssigner.java b/src/main/java/dan200/computercraft/shared/util/IDAssigner.java index b1eb6910e..489e1c075 100644 --- a/src/main/java/dan200/computercraft/shared/util/IDAssigner.java +++ b/src/main/java/dan200/computercraft/shared/util/IDAssigner.java @@ -1,5 +1,7 @@ package dan200.computercraft.shared.util; +import dan200.computercraft.ComputerCraft; + import java.io.*; public class IDAssigner @@ -50,6 +52,7 @@ public class IDAssigner } catch( NumberFormatException e ) { + ComputerCraft.log.error( "Unexpected file '" + content + "' in '" + location.getAbsolutePath() + "'", e ); } } } @@ -82,7 +85,7 @@ public class IDAssigner } catch( IOException e ) { - e.printStackTrace(); + ComputerCraft.log.error( "Cannot open ID file '" + lastidFile + "'", e ); return 0; } @@ -92,7 +95,7 @@ public class IDAssigner } catch( NumberFormatException e ) { - e.printStackTrace(); + ComputerCraft.log.error( "Cannot parse ID file '" + lastidFile + "', perhaps it is corrupt?", e ); return 0; } } @@ -107,8 +110,7 @@ public class IDAssigner } catch( IOException e ) { - System.out.println( "An error occured while trying to create the computer folder. Please check you have relevant permissions." ); - e.printStackTrace(); + ComputerCraft.log.error( "An error occured while trying to create the computer folder. Please check you have relevant permissions.", e ); } return id; diff --git a/src/main/resources/assets/computercraft/lang/en_US.lang b/src/main/resources/assets/computercraft/lang/en_US.lang index 98361fac9..18ee56160 100644 --- a/src/main/resources/assets/computercraft/lang/en_US.lang +++ b/src/main/resources/assets/computercraft/lang/en_US.lang @@ -44,6 +44,7 @@ gui.computercraft:config.http_enable=Enable HTTP API gui.computercraft:config.http_whitelist=HTTP whitelist gui.computercraft:config.disable_lua51_features=Disable Lua 5.1 features gui.computercraft:config.default_computer_settings=Default Computer settings +gui.computercraft:config.log_peripheral_errors=Log peripheral errors gui.computercraft:config.enable_command_block=Enable command block peripheral gui.computercraft:config.modem_range=Modem range (default) gui.computercraft:config.modem_high_altitude_range=Modem range (high-altitude)