Changeset 10819 in josm


Ignore:
Timestamp:
2016-08-15T23:33:32+02:00 (4 years ago)
Author:
Don-vip
Message:

fix #13352 - new bug report queue (patch by michael2402) - gsoc-core

Location:
trunk
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r10809 r10819  
    7777import org.openstreetmap.josm.tools.Utils;
    7878import org.openstreetmap.josm.tools.bugreport.BugReport;
    79 import org.openstreetmap.josm.tools.bugreport.BugReportExceptionHandler;
    8079
    8180/**
     
    845844            g.setPaintMode();
    846845        } 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();
    849847        }
    850848    }
     
    855853    @Override
    856854    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();
    858861            return;
    859862        }
     
    933936        }
    934937
    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();
    943942        }
    944943
     
    947946            drawWorldBorders(tempG);
    948947        } 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();
    950950        }
    951951
     
    989989    }
    990990
     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
    9911003    private void drawWorldBorders(Graphics2D tempG) {
    9921004        tempG.setColor(Color.WHITE);
     
    10151027            initialViewport = null;
    10161028        }
    1017         if (BugReportExceptionHandler.exceptionHandlingInProgress())
    1018             return false;
    10191029
    10201030        if (getCenter() == null)
  • trunk/src/org/openstreetmap/josm/tools/bugreport/BugReportDialog.java

    r10791 r10819  
    1717import javax.swing.JDialog;
    1818import javax.swing.JLabel;
     19import javax.swing.JOptionPane;
    1920import javax.swing.JPanel;
    2021import javax.swing.UIManager;
     
    2223import org.openstreetmap.josm.Main;
    2324import org.openstreetmap.josm.actions.ExpertToggleAction;
     25import org.openstreetmap.josm.gui.preferences.plugin.PluginPreference;
     26import org.openstreetmap.josm.gui.util.GuiHelper;
    2427import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
    2528import org.openstreetmap.josm.gui.widgets.UrlLabel;
     29import org.openstreetmap.josm.plugins.PluginDownloadTask;
     30import org.openstreetmap.josm.plugins.PluginHandler;
    2631import org.openstreetmap.josm.tools.GBC;
    2732import org.openstreetmap.josm.tools.ImageProvider;
    2833import org.openstreetmap.josm.tools.InputMapUtils;
     34import org.openstreetmap.josm.tools.bugreport.BugReportQueue.SuppressionMode;
    2935
    3036/**
     
    4147    private final BugReport report;
    4248    private final DebugTextDisplay textPanel;
    43     private JCheckBox cbSuppress;
     49    private JCheckBox cbSuppressSingle;
     50    private JCheckBox cbSuppressAll;
    4451
    4552    /**
     
    5663
    5764        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.
    5966
    6067        addCreateTicketSection();
     
    146153    private void addIgnoreButton() {
    147154        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));
    151161        JButton ignore = new JButton(tr("Ignore this error."));
    152162        ignore.addActionListener(e -> closeDialog());
    153         panel.add(ignore, GBC.eol());
     163        panel.add(ignore, GBC.std(1, 0).span(1, 2).anchor(GBC.CENTER));
    154164        content.add(panel, GBC.eol().fill(GBC.HORIZONTAL).insets(20));
    155165    }
     
    160170     */
    161171    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);
    163183        pack();
    164184    }
     
    168188     * @return <code>true</code> if the user wishes to suppress errors.
    169189     */
    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        }
    172198    }
    173199
     
    199225        return null;
    200226    }
     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    }
    201265}
  • trunk/src/org/openstreetmap/josm/tools/bugreport/BugReportExceptionHandler.java

    r10649 r10819  
    11// License: GPL. For details, see LICENSE file.
    22package 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;
    133
    144/**
     
    199 */
    2010public 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             @Override
    37             public void run() {
    38                 // Then ask for submitting a bug report, for exceptions thrown from a plugin too, unless updated to a new version
    39                 if (pluginDownloadTask == null) {
    40                     askForBugReport(e);
    41                 } else {
    42                     // Ask for restart to install new plugin
    43                     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 exception
    54          */
    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         @Override
    72         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     }
    7711
    7812    @Override
     
    8620     */
    8721    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();
    11523    }
    11624
     
    12028     */
    12129    public static boolean exceptionHandlingInProgress() {
    122         return handlingInProgress;
     30        return BugReportQueue.getInstance().exceptionHandlingInProgress();
    12331    }
    12432}
  • trunk/src/org/openstreetmap/josm/tools/bugreport/ReportedException.java

    r10718 r10819  
    6666    public void warn() {
    6767        methodWarningFrom = BugReport.getCallingMethod(2);
    68         // TODO: Open the dialog.
     68        try {
     69            BugReportQueue.getInstance().submit(this);
     70        } catch (RuntimeException e) {
     71            e.printStackTrace();
     72        }
    6973    }
    7074
     
    243247    @Override
    244248    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    }
    252252
    253253    /**
     
    259259        return StreamUtils.toStream(CauseTraceIterator::new)
    260260                .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);
    261270    }
    262271
  • trunk/test/unit/org/openstreetmap/josm/tools/bugreport/BugReportExceptionHandlerTest.java

    r10649 r10819  
    2222
    2323    /**
    24      * Unit test for {@link BugReportExceptionHandler.BugReporterThread#askForBugReport} method.
    25      */
    26     @Test
    27     public void testAskForBugReport() {
    28         BugReportExceptionHandler.BugReporterThread.askForBugReport(new Exception("testAskForBugReport"));
    29     }
    30 
    31     /**
    3224     * Unit test for {@link BugReportExceptionHandler#handleException} method.
    3325     */
Note: See TracChangeset for help on using the changeset viewer.