mirror of https://github.com/FreeCol/freecol.git
Handles uncaught errors (OutOfMemoryError, StackOverflowError etc) by freeing memory, showing an error message and force quit.
This commit is contained in:
parent
eabb0ea56b
commit
90e4df323e
|
@ -2789,6 +2789,7 @@ model.unit.hardyPioneer.noMoreTools=%location%: Your Hardy Pioneer has used up a
|
|||
# -10-- Client
|
||||
|
||||
# main: main() and support in FreeCol.java
|
||||
error.seriousError=An error occurred that is forcing FreeCol to exit. Please refer to the log file for more information.
|
||||
error.couldNotFind=An error occurred because file %name% could not be found
|
||||
error.couldNotLoad=An error occurred while trying to load the game from file %name%
|
||||
error.couldNotLoadDifficulty=An error occurred while trying to load difficulty options from file %name%.
|
||||
|
|
|
@ -71,6 +71,9 @@ public final class FreeColClient {
|
|||
|
||||
private static final Logger logger = Logger.getLogger(FreeColClient.class.getName());
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private byte[] memoryToBeFreedOnOutOfMemory = new byte[10 * 1024 * 1024];
|
||||
|
||||
private final ConnectController connectController;
|
||||
|
||||
private final PreGameController preGameController;
|
||||
|
@ -167,6 +170,7 @@ public final class FreeColClient {
|
|||
if (FreeCol.getHeadless() && savedGame == null && spec == null) {
|
||||
FreeCol.fatal(logger, Messages.message("client.headlessRequires"));
|
||||
}
|
||||
|
||||
mapEditor = false;
|
||||
|
||||
// Look for base data directory and get base resources loaded.
|
||||
|
@ -246,6 +250,8 @@ public final class FreeColClient {
|
|||
// Initialize Sound (depends on client options)
|
||||
this.soundController = new SoundController(this, sound);
|
||||
|
||||
overrideDefaultUncaughtExceptionHandler();
|
||||
|
||||
/*
|
||||
* Please do NOT move preloading before mods are loaded -- as that
|
||||
* might cause some images to be loaded from base and other images
|
||||
|
@ -1010,4 +1016,31 @@ public final class FreeColClient {
|
|||
}
|
||||
FreeCol.quit(0);
|
||||
}
|
||||
|
||||
private void overrideDefaultUncaughtExceptionHandler() {
|
||||
// This overrides the handler in FreeCol:
|
||||
Thread.setDefaultUncaughtExceptionHandler((Thread thread, Throwable e) -> {
|
||||
// Free enough space to ensure we can perform the next operations.
|
||||
if (e instanceof Error) {
|
||||
memoryToBeFreedOnOutOfMemory = null;
|
||||
gui.emergencyPurge();
|
||||
}
|
||||
|
||||
final boolean seriousError = (e instanceof Error);
|
||||
try {
|
||||
logger.log(Level.WARNING, "Uncaught exception from thread: " + thread, e);
|
||||
|
||||
if (seriousError) {
|
||||
gui.showErrorPanel(Messages.message("error.seriousError"), () -> {
|
||||
System.exit(1);
|
||||
});
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
if (seriousError) {
|
||||
t.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2506,4 +2506,14 @@ public class GUI extends FreeColClientHolder {
|
|||
public boolean canGameChangingModsBeAdded() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A method to be called only on serious Errors in order
|
||||
* to ensure sufficient memory for displaying an error
|
||||
* message.
|
||||
*/
|
||||
public void emergencyPurge() {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ import net.sf.freecol.FreeCol;
|
|||
import net.sf.freecol.client.ClientOptions;
|
||||
import net.sf.freecol.client.FreeColClient;
|
||||
import net.sf.freecol.client.control.MapTransform;
|
||||
import net.sf.freecol.client.control.SoundController;
|
||||
import net.sf.freecol.client.gui.animation.Animation;
|
||||
import net.sf.freecol.client.gui.animation.Animations;
|
||||
// Special dialogs and panels
|
||||
|
@ -1373,6 +1374,18 @@ public class SwingGUI extends GUI {
|
|||
refresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void emergencyPurge() {
|
||||
imageCache.clear();
|
||||
|
||||
final SoundController sc = getFreeColClient().getSoundController();
|
||||
sc.setDefaultPlaylist(List.of());
|
||||
sc.playMusic(null);
|
||||
}
|
||||
|
||||
|
||||
// Highest level panel and dialog handling
|
||||
|
||||
|
|
Loading…
Reference in New Issue