X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fnet%2Fsf%2Fopenrocket%2Fgui%2Fmain%2FExceptionHandler.java;h=83301da729d0645a2e3c26c398eb835002c55551;hb=b1c573776a50dbf618f27898cdad90cafe9addc2;hp=702c3025cf5d866644f5a85dbf93d9e395f57bff;hpb=def27b03bd9ebe6628421ec61112ebe4f45f043d;p=debian%2Fopenrocket diff --git a/src/net/sf/openrocket/gui/main/ExceptionHandler.java b/src/net/sf/openrocket/gui/main/ExceptionHandler.java index 702c3025..83301da7 100644 --- a/src/net/sf/openrocket/gui/main/ExceptionHandler.java +++ b/src/net/sf/openrocket/gui/main/ExceptionHandler.java @@ -4,11 +4,16 @@ import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import net.sf.openrocket.gui.dialogs.BugReportDialog; +import net.sf.openrocket.logging.LogHelper; +import net.sf.openrocket.logging.TraceException; +import net.sf.openrocket.startup.Application; public class ExceptionHandler implements Thread.UncaughtExceptionHandler { - - private static final int MEMORY_RESERVE = 512*1024; + + private static final LogHelper log = Application.getLogger(); + + private static final int MEMORY_RESERVE = 512 * 1024; /** * A memory reserve of 0.5 MB of memory, that can be freed when showing the dialog. @@ -19,51 +24,61 @@ public class ExceptionHandler implements Thread.UncaughtExceptionHandler { private static ExceptionHandler instance = null; - + private volatile boolean handling = false; - - + + @Override - public void uncaughtException(final Thread t, final Throwable e) { + public void uncaughtException(final Thread thread, final Throwable throwable) { // Free memory reserve if out of memory - if (isOutOfMemoryError(e)) { + if (isOutOfMemoryError(throwable)) { memoryReserve = null; handling = false; + log.error("Out of memory error detected", throwable); + } + + if (isNonFatalJREBug(throwable)) { + log.warn("Ignoring non-fatal JRE bug", throwable); + return; + } + + log.error("Handling uncaught exception on thread=" + thread, throwable); + throwable.printStackTrace(); + + if (handling) { + log.warn("Exception is currently being handled, ignoring"); + return; } - - e.printStackTrace(); try { - - if (handling) { - System.err.println("Exception is currently being handled, ignoring:"); - e.printStackTrace(); - return; - } - handling = true; // Show on the EDT if (SwingUtilities.isEventDispatchThread()) { - showDialog(t, e); + log.info("Exception handler running on EDT, showing dialog"); + showDialog(thread, throwable); } else { - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - showDialog(t, e); - } - }); + log.info("Exception handler not on EDT, invoking dialog on EDT"); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + showDialog(thread, throwable); + } + }); } } catch (Throwable ex) { // Make sure the handler does not throw any exceptions try { + log.error("Caught exception while handling exception", ex); System.err.println("Exception in exception handler, dumping exception:"); ex.printStackTrace(); - } catch (Throwable ignore) { } + } catch (Exception ignore) { + } } finally { // Mark handling as completed @@ -71,27 +86,35 @@ public class ExceptionHandler implements Thread.UncaughtExceptionHandler { } } - + /** * Handle an error condition programmatically without throwing an exception. * This can be used in cases where recovery of the error is desirable. + *
+ * This method is guaranteed never to throw an exception, and can thus be safely + * used in finally blocks. * * @param message the error message. */ public static void handleErrorCondition(String message) { + log.error(1, message, new TraceException()); handleErrorCondition(new InternalException(message)); } - + /** * Handle an error condition programmatically without throwing an exception. * This can be used in cases where recovery of the error is desirable. + *
+ * This method is guaranteed never to throw an exception, and can thus be safely + * used in finally blocks. * * @param message the error message. * @param exception the exception that occurred. */ - public static void handleErrorCondition(String message, Exception exception) { + public static void handleErrorCondition(String message, Throwable exception) { + log.error(1, message, exception); handleErrorCondition(new InternalException(message, exception)); } @@ -99,33 +122,39 @@ public class ExceptionHandler implements Thread.UncaughtExceptionHandler { /** * Handle an error condition programmatically without throwing an exception. * This can be used in cases where recovery of the error is desirable. + *
+ * This method is guaranteed never to throw an exception, and can thus be safely
+ * used in finally blocks.
*
* @param exception the exception that occurred.
*/
- public static void handleErrorCondition(final Exception exception) {
- final ExceptionHandler handler;
-
+ public static void handleErrorCondition(final Throwable exception) {
try {
-
- if (instance == null) {
- handler = new ExceptionHandler();
- } else {
- handler = instance;
+ if (!(exception instanceof InternalException)) {
+ log.error(1, "Error occurred", exception);
}
-
final Thread thread = Thread.currentThread();
-
+ final ExceptionHandler handler = instance;
+
+ if (handler == null) {
+ log.error("Error condition occurred before exception handling has been initialized", exception);
+ return;
+ }
+
if (SwingUtilities.isEventDispatchThread()) {
+ log.info("Running in EDT, showing dialog");
handler.showDialog(thread, exception);
} else {
- SwingUtilities.invokeAndWait(new Runnable() {
+ log.info("Not in EDT, invoking dialog later");
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
public void run() {
handler.showDialog(thread, exception);
}
});
}
} catch (Exception e) {
- e.printStackTrace();
+ log.error("Exception occurred in error handler", e);
}
}
@@ -140,11 +169,12 @@ public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
// Out of memory
if (isOutOfMemoryError(e)) {
- JOptionPane.showMessageDialog(null,
- new Object[] {
- "OpenRocket can out of available memory!",
- "You should immediately close unnecessary design windows,",
- "save any unsaved designs and restart OpenRocket!"
+ log.info("Showing out-of-memory dialog");
+ JOptionPane.showMessageDialog(null,
+ new Object[] {
+ "OpenRocket is out of available memory!",
+ "You should immediately close unnecessary design windows,",
+ "save any unsaved designs and restart OpenRocket!"
}, "Out of memory", JOptionPane.ERROR_MESSAGE);
return;
}
@@ -156,42 +186,45 @@ public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
}
// Unknown Error
- if (!(e instanceof Exception)) {
- JOptionPane.showMessageDialog(null,
- new Object[] {
- "An unknown Java error occurred:",
- msg,
- "You should immediately close unnecessary design windows,
" +
- "save any unsaved designs and restart OpenRocket!"
+ if (!(e instanceof Exception) && !(e instanceof LinkageError)) {
+ log.info("Showing Error dialog");
+ JOptionPane.showMessageDialog(null,
+ new Object[] {
+ "An unknown Java error occurred:",
+ msg,
+ "You should immediately close unnecessary design windows,
" +
+ "save any unsaved designs and restart OpenRocket!"
}, "Unknown Java error", JOptionPane.ERROR_MESSAGE);
return;
}
-
+
// Normal exception, show question dialog
+ log.info("Showing Exception dialog");
int selection = JOptionPane.showOptionDialog(null, new Object[] {
"OpenRocket encountered an uncaught exception. This typically signifies " +
- "a bug in the software.",
+ "a bug in the software.",
" " + msg + "",
" ",
"Please take a moment to report this bug to the developers.",
"This can be done automatically if you have an Internet connection."
- }, "Uncaught exception", JOptionPane.DEFAULT_OPTION,
- JOptionPane.ERROR_MESSAGE, null,
+ }, "Uncaught exception", JOptionPane.DEFAULT_OPTION,
+ JOptionPane.ERROR_MESSAGE, null,
new Object[] { "View bug report", "Close" }, "View bug report");
if (selection != 0) {
// User cancelled
+ log.user("User chose not to fill bug report");
return;
}
// Show bug report dialog
+ log.user("User requested sending bug report");
BugReportDialog.showExceptionDialog(null, t, e);
-
}
-
+
/**
* Registers the uncaught exception handler. This should be used to ensure that
* all necessary registrations are performed.
@@ -217,13 +250,13 @@ public class ExceptionHandler implements Thread.UncaughtExceptionHandler {
*/
private static void reserveMemory() {
memoryReserve = new byte[MEMORY_RESERVE];
- for (int i=0; i