- Timestamp:
- 2016-08-15T23:33:32+02:00 (8 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/MapView.java
r10809 r10819 77 77 import org.openstreetmap.josm.tools.Utils; 78 78 import org.openstreetmap.josm.tools.bugreport.BugReport; 79 import org.openstreetmap.josm.tools.bugreport.BugReportExceptionHandler;80 79 81 80 /** … … 845 844 g.setPaintMode(); 846 845 } catch (RuntimeException t) { 847 //TODO: only display. 848 throw BugReport.intercept(t).put("layer", layer).put("bounds", box); 846 BugReport.intercept(t).put("layer", layer).put("bounds", box).warn(); 849 847 } 850 848 } … … 855 853 @Override 856 854 public void paint(Graphics g) { 857 if (!prepareToDraw()) { 855 try { 856 if (!prepareToDraw()) { 857 return; 858 } 859 } catch (RuntimeException e) { 860 BugReport.intercept(e).put("center", () -> getCenter()).warn(); 858 861 return; 859 862 } … … 933 936 } 934 937 935 synchronized (temporaryLayers) { 936 for (MapViewPaintable mvp : temporaryLayers) { 937 try { 938 mvp.paint(tempG, this, box); 939 } catch (RuntimeException e) { 940 throw BugReport.intercept(e).put("mvp", mvp); 941 } 942 } 938 try { 939 drawTemporaryLayers(tempG, box); 940 } catch (RuntimeException e) { 941 BugReport.intercept(e).put("temporaryLayers", temporaryLayers).warn(); 943 942 } 944 943 … … 947 946 drawWorldBorders(tempG); 948 947 } catch (RuntimeException e) { 949 throw BugReport.intercept(e).put("bounds", getProjection()::getWorldBoundsLatLon); 948 // getProjection() needs to be inside lambda to catch errors. 949 BugReport.intercept(e).put("bounds", () -> getProjection().getWorldBoundsLatLon()).warn(); 950 950 } 951 951 … … 989 989 } 990 990 991 private void drawTemporaryLayers(Graphics2D tempG, Bounds box) { 992 synchronized (temporaryLayers) { 993 for (MapViewPaintable mvp : temporaryLayers) { 994 try { 995 mvp.paint(tempG, this, box); 996 } catch (RuntimeException e) { 997 throw BugReport.intercept(e).put("mvp", mvp); 998 } 999 } 1000 } 1001 } 1002 991 1003 private void drawWorldBorders(Graphics2D tempG) { 992 1004 tempG.setColor(Color.WHITE); … … 1015 1027 initialViewport = null; 1016 1028 } 1017 if (BugReportExceptionHandler.exceptionHandlingInProgress())1018 return false;1019 1029 1020 1030 if (getCenter() == null) -
trunk/src/org/openstreetmap/josm/tools/bugreport/BugReportDialog.java
r10791 r10819 17 17 import javax.swing.JDialog; 18 18 import javax.swing.JLabel; 19 import javax.swing.JOptionPane; 19 20 import javax.swing.JPanel; 20 21 import javax.swing.UIManager; … … 22 23 import org.openstreetmap.josm.Main; 23 24 import org.openstreetmap.josm.actions.ExpertToggleAction; 25 import org.openstreetmap.josm.gui.preferences.plugin.PluginPreference; 26 import org.openstreetmap.josm.gui.util.GuiHelper; 24 27 import org.openstreetmap.josm.gui.widgets.JMultilineLabel; 25 28 import org.openstreetmap.josm.gui.widgets.UrlLabel; 29 import org.openstreetmap.josm.plugins.PluginDownloadTask; 30 import org.openstreetmap.josm.plugins.PluginHandler; 26 31 import org.openstreetmap.josm.tools.GBC; 27 32 import org.openstreetmap.josm.tools.ImageProvider; 28 33 import org.openstreetmap.josm.tools.InputMapUtils; 34 import org.openstreetmap.josm.tools.bugreport.BugReportQueue.SuppressionMode; 29 35 30 36 /** … … 41 47 private final BugReport report; 42 48 private final DebugTextDisplay textPanel; 43 private JCheckBox cbSuppress; 49 private JCheckBox cbSuppressSingle; 50 private JCheckBox cbSuppressAll; 44 51 45 52 /** … … 56 63 57 64 addUpToDateSection(); 58 // TODO: Notify user about plugin updates 65 // TODO: Notify user about plugin updates, then remove that notification that is displayed before this dialog is displayed. 59 66 60 67 addCreateTicketSection(); … … 146 153 private void addIgnoreButton() { 147 154 JPanel panel = new JPanel(new GridBagLayout()); 148 cbSuppress = new JCheckBox(tr("Suppress further error dialogs for this session.")); 149 cbSuppress.setVisible(false); 150 panel.add(cbSuppress, GBC.std().fill(GBC.HORIZONTAL)); 155 cbSuppressSingle = new JCheckBox(tr("Suppress this error for this session.")); 156 cbSuppressSingle.setVisible(false); 157 panel.add(cbSuppressSingle, GBC.std(0, 0).fill(GBC.HORIZONTAL)); 158 cbSuppressAll = new JCheckBox(tr("Suppress further error dialogs for this session.")); 159 cbSuppressAll.setVisible(false); 160 panel.add(cbSuppressAll, GBC.std(0, 1).fill(GBC.HORIZONTAL)); 151 161 JButton ignore = new JButton(tr("Ignore this error.")); 152 162 ignore.addActionListener(e -> closeDialog()); 153 panel.add(ignore, GBC. eol());163 panel.add(ignore, GBC.std(1, 0).span(1, 2).anchor(GBC.CENTER)); 154 164 content.add(panel, GBC.eol().fill(GBC.HORIZONTAL).insets(20)); 155 165 } … … 160 170 */ 161 171 public void setShowSuppress(boolean showSuppress) { 162 cbSuppress.setVisible(showSuppress); 172 cbSuppressSingle.setVisible(showSuppress); 173 pack(); 174 } 175 176 /** 177 * Shows or hides the suppress all errors button 178 * @param showSuppress <code>true</code> to show the suppress errors checkbox. 179 * @since 10819 180 */ 181 public void setShowSuppressAll(boolean showSuppress) { 182 cbSuppressAll.setVisible(showSuppress); 163 183 pack(); 164 184 } … … 168 188 * @return <code>true</code> if the user wishes to suppress errors. 169 189 */ 170 public boolean shouldSuppressFurtherErrors() { 171 return cbSuppress.isSelected(); 190 public SuppressionMode shouldSuppressFurtherErrors() { 191 if (cbSuppressAll.isSelected()) { 192 return SuppressionMode.ALL; 193 } else if (cbSuppressSingle.isSelected()) { 194 return SuppressionMode.SAME; 195 } else { 196 return SuppressionMode.NONE; 197 } 172 198 } 173 199 … … 199 225 return null; 200 226 } 227 228 /** 229 * Show the bug report for a given exception 230 * @param e The exception to display 231 * @param exceptionCounter A counter of how many exceptions have already been worked on 232 * @return The new suppression status 233 * @since 10819 234 */ 235 public static SuppressionMode showFor(ReportedException e, int exceptionCounter) { 236 if (e.isOutOfMemory()) { 237 // do not translate the string, as translation may raise an exception 238 JOptionPane.showMessageDialog(Main.parent, "JOSM is out of memory. " + 239 "Strange things may happen.\nPlease restart JOSM with the -Xmx###M option,\n" + 240 "where ### is the number of MB assigned to JOSM (e.g. 256).\n" + 241 "Currently, " + Runtime.getRuntime().maxMemory()/1024/1024 + " MB are available to JOSM.", 242 "Error", 243 JOptionPane.ERROR_MESSAGE 244 ); 245 return SuppressionMode.NONE; 246 } else { 247 return GuiHelper.runInEDTAndWaitAndReturn(() -> { 248 PluginDownloadTask downloadTask = PluginHandler.updateOrdisablePluginAfterException(e); 249 if (downloadTask != null) { 250 // Ask for restart to install new plugin 251 PluginPreference.notifyDownloadResults( 252 Main.parent, downloadTask, !downloadTask.getDownloadedPlugins().isEmpty()); 253 return SuppressionMode.NONE; 254 } 255 256 BugReport report = new BugReport(e); 257 BugReportDialog dialog = new BugReportDialog(report); 258 dialog.setShowSuppress(exceptionCounter > 0); 259 dialog.setShowSuppressAll(exceptionCounter > 1); 260 dialog.setVisible(true); 261 return dialog.shouldSuppressFurtherErrors(); 262 }); 263 } 264 } 201 265 } -
trunk/src/org/openstreetmap/josm/tools/bugreport/BugReportExceptionHandler.java
r10649 r10819 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.tools.bugreport; 3 4 import java.awt.GraphicsEnvironment;5 6 import javax.swing.JOptionPane;7 import javax.swing.SwingUtilities;8 9 import org.openstreetmap.josm.Main;10 import org.openstreetmap.josm.gui.preferences.plugin.PluginPreference;11 import org.openstreetmap.josm.plugins.PluginDownloadTask;12 import org.openstreetmap.josm.plugins.PluginHandler;13 3 14 4 /** … … 19 9 */ 20 10 public final class BugReportExceptionHandler implements Thread.UncaughtExceptionHandler { 21 22 private static boolean handlingInProgress;23 private static volatile BugReporterThread bugReporterThread;24 private static int exceptionCounter;25 private static boolean suppressExceptionDialogs;26 27 static final class BugReporterThread extends Thread {28 29 private final class BugReporterWorker implements Runnable {30 private final PluginDownloadTask pluginDownloadTask;31 32 private BugReporterWorker(PluginDownloadTask pluginDownloadTask) {33 this.pluginDownloadTask = pluginDownloadTask;34 }35 36 @Override37 public void run() {38 // Then ask for submitting a bug report, for exceptions thrown from a plugin too, unless updated to a new version39 if (pluginDownloadTask == null) {40 askForBugReport(e);41 } else {42 // Ask for restart to install new plugin43 PluginPreference.notifyDownloadResults(44 Main.parent, pluginDownloadTask, !pluginDownloadTask.getDownloadedPlugins().isEmpty());45 }46 }47 }48 49 private final Throwable e;50 51 /**52 * Constructs a new {@code BugReporterThread}.53 * @param t the exception54 */55 private BugReporterThread(Throwable t) {56 super("Bug Reporter");57 this.e = t;58 }59 60 static void askForBugReport(final Throwable e) {61 if (GraphicsEnvironment.isHeadless()) {62 return;63 }64 BugReport report = new BugReport(BugReport.intercept(e));65 BugReportDialog dialog = new BugReportDialog(report);66 dialog.setShowSuppress(exceptionCounter > 1);67 dialog.setVisible(true);68 suppressExceptionDialogs = dialog.shouldSuppressFurtherErrors();69 }70 71 @Override72 public void run() {73 // Give the user a chance to deactivate the plugin which threw the exception (if it was thrown from a plugin)74 SwingUtilities.invokeLater(new BugReporterWorker(PluginHandler.updateOrdisablePluginAfterException(e)));75 }76 }77 11 78 12 @Override … … 86 20 */ 87 21 public static synchronized void handleException(final Throwable e) { 88 if (handlingInProgress || suppressExceptionDialogs) 89 return; // we do not handle secondary exceptions, this gets too messy 90 if (bugReporterThread != null && bugReporterThread.isAlive()) 91 return; 92 handlingInProgress = true; 93 exceptionCounter++; 94 try { 95 Main.error(e); 96 if (Main.parent != null) { 97 if (e instanceof OutOfMemoryError) { 98 // do not translate the string, as translation may raise an exception 99 JOptionPane.showMessageDialog(Main.parent, "JOSM is out of memory. " + 100 "Strange things may happen.\nPlease restart JOSM with the -Xmx###M option,\n" + 101 "where ### is the number of MB assigned to JOSM (e.g. 256).\n" + 102 "Currently, " + Runtime.getRuntime().maxMemory()/1024/1024 + " MB are available to JOSM.", 103 "Error", 104 JOptionPane.ERROR_MESSAGE 105 ); 106 return; 107 } 108 109 bugReporterThread = new BugReporterThread(e); 110 bugReporterThread.start(); 111 } 112 } finally { 113 handlingInProgress = false; 114 } 22 BugReport.intercept(e).warn(); 115 23 } 116 24 … … 120 28 */ 121 29 public static boolean exceptionHandlingInProgress() { 122 return handlingInProgress;30 return BugReportQueue.getInstance().exceptionHandlingInProgress(); 123 31 } 124 32 } -
trunk/src/org/openstreetmap/josm/tools/bugreport/ReportedException.java
r10718 r10819 66 66 public void warn() { 67 67 methodWarningFrom = BugReport.getCallingMethod(2); 68 // TODO: Open the dialog. 68 try { 69 BugReportQueue.getInstance().submit(this); 70 } catch (RuntimeException e) { 71 e.printStackTrace(); 72 } 69 73 } 70 74 … … 243 247 @Override 244 248 public String toString() { 245 return new StringBuilder(48) 246 .append("CrashReportedException [on thread ") 247 .append(caughtOnThread) 248 .append(']') 249 .toString(); 250 } 251 249 return "ReportedException [thread=" + caughtOnThread + ", exception=" + exception 250 + ", methodWarningFrom=" + methodWarningFrom + "]"; 251 } 252 252 253 253 /** … … 259 259 return StreamUtils.toStream(CauseTraceIterator::new) 260 260 .anyMatch(t -> t instanceof ConcurrentModificationException || t instanceof InvocationTargetException); 261 } 262 263 /** 264 * Check if this is caused by an out of memory situaition 265 * @return <code>true</code> if it is. 266 * @since 10819 267 */ 268 public boolean isOutOfMemory() { 269 return StreamUtils.toStream(CauseTraceIterator::new).anyMatch(t -> t instanceof OutOfMemoryError); 261 270 } 262 271 -
trunk/test/unit/org/openstreetmap/josm/tools/bugreport/BugReportExceptionHandlerTest.java
r10649 r10819 22 22 23 23 /** 24 * Unit test for {@link BugReportExceptionHandler.BugReporterThread#askForBugReport} method.25 */26 @Test27 public void testAskForBugReport() {28 BugReportExceptionHandler.BugReporterThread.askForBugReport(new Exception("testAskForBugReport"));29 }30 31 /**32 24 * Unit test for {@link BugReportExceptionHandler#handleException} method. 33 25 */
Note:
See TracChangeset
for help on using the changeset viewer.