Ticket #12652: patch-bugreport-longer-error-message.patch

File patch-bugreport-longer-error-message.patch, 17.4 KB (added by michael2402, 4 years ago)
  • src/org/openstreetmap/josm/actions/ReportBugAction.java

    diff --git a/src/org/openstreetmap/josm/actions/ReportBugAction.java b/src/org/openstreetmap/josm/actions/ReportBugAction.java
    index 28ddc37..c7caab4 100644
    a b import static org.openstreetmap.josm.tools.I18n.tr; 
    66import java.awt.event.ActionEvent;
    77import java.awt.event.KeyEvent;
    88
    9 import org.openstreetmap.josm.tools.BugReportExceptionHandler;
    10 import org.openstreetmap.josm.tools.OpenBrowser;
    119import org.openstreetmap.josm.tools.Shortcut;
    12 import org.openstreetmap.josm.tools.Utils;
     10import org.openstreetmap.josm.tools.bugreport.BugReportSender;
    1311
    1412/**
    1513 * Reports a ticket to JOSM bugtracker.
    import org.openstreetmap.josm.tools.Utils; 
    1715 */
    1816public class ReportBugAction extends JosmAction {
    1917
     18    private final String text;
     19
    2020    /**
    21      * Constructs a new {@code ReportBugAction}.
     21     * Constructs a new {@code ReportBugAction} that reports the normal status report.
    2222     */
    2323    public ReportBugAction() {
     24        this(ShowStatusReportAction.getReportHeader());
     25    }
     26
     27    /**
     28     * Constructs a new {@link ReportBugAction} for the given debug text.
     29     * @param text The text to send
     30     */
     31    public ReportBugAction(String text) {
    2432        super(tr("Report bug"), "bug", tr("Report a ticket to JOSM bugtracker"),
    2533                Shortcut.registerShortcut("reportbug", tr("Report a ticket to JOSM bugtracker"),
    2634                        KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), true);
     35        this.text = text;
    2736    }
    2837
    2938    @Override
    3039    public void actionPerformed(ActionEvent e) {
    31         reportBug();
     40        BugReportSender.reportBug(text);
    3241    }
    3342
    3443    /**
    3544     * Reports a ticket to JOSM bugtracker.
     45     * @deprecated Use {@link BugReportSender#reportBug(String)}
    3646     */
     47    @Deprecated
    3748    public static void reportBug() {
    38         reportBug(ShowStatusReportAction.getReportHeader());
     49        BugReportSender.reportBug(ShowStatusReportAction.getReportHeader());
    3950    }
    4051
    4152    /**
    4253     * Reports a ticket to JOSM bugtracker with given status report.
     54     * Replaced by {@link BugReportSender#reportBug(String)}
    4355     * @param report Status report header containing technical, non-personal information
     56     * @deprecated Use {@link BugReportSender#reportBug(String)}
    4457     */
     58    @Deprecated
    4559    public static void reportBug(String report) {
    46         OpenBrowser.displayUrl(BugReportExceptionHandler.getBugReportUrl(
    47                 Utils.strip(report)).toExternalForm());
     60        BugReportSender.reportBug(report);
    4861    }
    4962}
  • src/org/openstreetmap/josm/actions/ShowStatusReportAction.java

    diff --git a/src/org/openstreetmap/josm/actions/ShowStatusReportAction.java b/src/org/openstreetmap/josm/actions/ShowStatusReportAction.java
    index 1f8f5fb..53c7d92 100644
    a b import java.util.Map; 
    1919import java.util.Map.Entry;
    2020import java.util.Set;
    2121
    22 import javax.swing.JScrollPane;
    23 
    2422import org.openstreetmap.josm.Main;
    2523import org.openstreetmap.josm.data.Version;
    2624import org.openstreetmap.josm.data.osm.DataSet;
    2725import org.openstreetmap.josm.data.osm.DatasetConsistencyTest;
    2826import org.openstreetmap.josm.data.preferences.Setting;
    2927import org.openstreetmap.josm.gui.ExtendedDialog;
    30 import org.openstreetmap.josm.gui.widgets.JosmTextArea;
    3128import org.openstreetmap.josm.plugins.PluginHandler;
    3229import org.openstreetmap.josm.tools.PlatformHookUnixoid;
    3330import org.openstreetmap.josm.tools.Shortcut;
    34 import org.openstreetmap.josm.tools.Utils;
     31import org.openstreetmap.josm.tools.bugreport.BugReportSender;
     32import org.openstreetmap.josm.tools.bugreport.DebugTextDisplay;
    3533
    3634/**
    3735 * @author xeen
    public final class ShowStatusReportAction extends JosmAction { 
    183181            Main.error(x);
    184182        }
    185183
    186         JosmTextArea ta = new JosmTextArea(text.toString());
    187         ta.setWrapStyleWord(true);
    188         ta.setLineWrap(true);
    189         ta.setEditable(false);
    190         JScrollPane sp = new JScrollPane(ta);
     184        DebugTextDisplay ta = new DebugTextDisplay(text.toString());
    191185
    192186        ExtendedDialog ed = new ExtendedDialog(Main.parent,
    193187                tr("Status Report"),
    194188                new String[] {tr("Copy to clipboard and close"), tr("Report bug"), tr("Close") });
    195189        ed.setButtonIcons(new String[] {"copy", "bug", "cancel" });
    196         ed.setContent(sp, false);
     190        ed.setContent(ta, false);
    197191        ed.setMinimumSize(new Dimension(380, 200));
    198192        ed.setPreferredSize(new Dimension(700, Main.parent.getHeight()-50));
    199193
    200194        switch (ed.showDialog().getValue()) {
    201             case 1: Utils.copyToClipboard(text.toString()); break;
    202             case 2: ReportBugAction.reportBug(reportHeader); break;
     195            case 1: ta.copyToClippboard(); break;
     196            case 2: BugReportSender.reportBug(reportHeader); break;
    203197        }
    204198    }
    205199}
  • src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java

    diff --git a/src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java b/src/org/openstreetmap/josm/tools/BugReportExceptionHandler.java
    index 0fac45f..f980e36 100644
    a b import java.nio.ByteBuffer; 
    1515import java.nio.charset.StandardCharsets;
    1616import java.util.zip.GZIPOutputStream;
    1717
     18import javax.swing.JButton;
    1819import javax.swing.JCheckBox;
    1920import javax.swing.JLabel;
    2021import javax.swing.JOptionPane;
    2122import javax.swing.JPanel;
    22 import javax.swing.JScrollPane;
    2323import javax.swing.SwingUtilities;
    2424
    2525import org.openstreetmap.josm.Main;
     26import org.openstreetmap.josm.actions.ReportBugAction;
    2627import org.openstreetmap.josm.actions.ShowStatusReportAction;
    2728import org.openstreetmap.josm.data.Version;
    2829import org.openstreetmap.josm.gui.ExtendedDialog;
    2930import org.openstreetmap.josm.gui.preferences.plugin.PluginPreference;
    3031import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
    31 import org.openstreetmap.josm.gui.widgets.JosmTextArea;
    3232import org.openstreetmap.josm.gui.widgets.UrlLabel;
    3333import org.openstreetmap.josm.plugins.PluginDownloadTask;
    3434import org.openstreetmap.josm.plugins.PluginHandler;
     35import org.openstreetmap.josm.tools.bugreport.BugReportSender;
     36import org.openstreetmap.josm.tools.bugreport.DebugTextDisplay;
    3537
    3638/**
    3739 * An exception handler that asks the user to send a bug report.
    public final class BugReportExceptionHandler implements Thread.UncaughtException 
    193195
    194196    private static void askForBugReport(final Throwable e) {
    195197        try {
    196             final int maxlen = 6000;
    197198            StringWriter stack = new StringWriter();
    198199            e.printStackTrace(new PrintWriter(stack));
    199200
    200201            String text = ShowStatusReportAction.getReportHeader() + stack.getBuffer().toString();
    201             String urltext = text.replaceAll("\r", "");
    202             if (urltext.length() > maxlen) {
    203                 urltext = urltext.substring(0, maxlen);
    204                 int idx = urltext.lastIndexOf('\n');
    205                 // cut whole line when not loosing too much
    206                 if (maxlen-idx < 200) {
    207                     urltext = urltext.substring(0, idx+1);
    208                 }
    209                 urltext += "...<snip>...\n";
    210             }
     202            text = text.replaceAll("\r", "");
    211203
    212204            JPanel p = new JPanel(new GridBagLayout());
    213205            p.add(new JMultilineLabel(
    public final class BugReportExceptionHandler implements Thread.UncaughtException 
    219211                    tr("You should also update your plugins. If neither of those help please " +
    220212                            "file a bug report in our bugtracker using this link:")),
    221213                            GBC.eol().fill(GridBagConstraints.HORIZONTAL));
    222             p.add(getBugReportUrlLabel(urltext), GBC.eop().insets(8, 0, 0, 0));
     214            p.add(new JButton(new ReportBugAction(text)), GBC.eop().insets(8, 0, 0, 0));
    223215            p.add(new JMultilineLabel(
    224216                    tr("There the error information provided below should already be " +
    225217                            "filled in for you. Please include information on how to reproduce " +
    public final class BugReportExceptionHandler implements Thread.UncaughtException 
    231223            p.add(new UrlLabel(Main.getJOSMWebsite()+"/newticket", 2), GBC.eop().insets(8, 0, 0, 0));
    232224
    233225            // Wiki formatting for manual copy-paste
    234             text = "{{{\n"+text+"}}}";
     226            DebugTextDisplay textarea = new DebugTextDisplay(text);
    235227
    236             if (Utils.copyToClipboard(text)) {
     228            if (textarea.copyToClippboard()) {
    237229                p.add(new JLabel(tr("(The text has already been copied to your clipboard.)")),
    238230                        GBC.eop().fill(GridBagConstraints.HORIZONTAL));
    239231            }
    240232
    241             JosmTextArea info = new JosmTextArea(text, 18, 60);
    242             info.setCaretPosition(0);
    243             info.setEditable(false);
    244             p.add(new JScrollPane(info), GBC.eop().fill());
     233            p.add(textarea, GBC.eop().fill());
    245234
    246235            for (Component c: p.getComponents()) {
    247236                if (c instanceof JMultilineLabel) {
    public final class BugReportExceptionHandler implements Thread.UncaughtException 
    264253    }
    265254
    266255    /**
    267      * Replies the URL to create a JOSM bug report with the given debug text
     256     * Replies the URL to create a JOSM bug report with the given debug text. GZip is used to reduce the length of the parameter.
    268257     * @param debugText The debug text to provide us
    269258     * @return The URL to create a JOSM bug report with the given debug text
     259     * @see BugReportSender#reportBug(String) if you want to send long debug texts along.
    270260     * @since 5849
    271261     */
    272262    public static URL getBugReportUrl(String debugText) {
  • new file src/org/openstreetmap/josm/tools/bugreport/BugReportSender.java

    diff --git a/src/org/openstreetmap/josm/tools/bugreport/BugReportSender.java b/src/org/openstreetmap/josm/tools/bugreport/BugReportSender.java
    new file mode 100644
    index 0000000..962c468
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.tools.bugreport;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.awt.GridBagConstraints;
     7import java.awt.GridBagLayout;
     8import java.io.IOException;
     9import java.io.InputStream;
     10import java.net.URL;
     11import java.nio.charset.StandardCharsets;
     12
     13import javax.swing.JOptionPane;
     14import javax.swing.JPanel;
     15import javax.swing.SwingUtilities;
     16import javax.xml.parsers.DocumentBuilder;
     17import javax.xml.parsers.DocumentBuilderFactory;
     18import javax.xml.parsers.ParserConfigurationException;
     19import javax.xml.xpath.XPath;
     20import javax.xml.xpath.XPathConstants;
     21import javax.xml.xpath.XPathExpressionException;
     22import javax.xml.xpath.XPathFactory;
     23
     24import org.openstreetmap.josm.Main;
     25import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
     26import org.openstreetmap.josm.gui.widgets.UrlLabel;
     27import org.openstreetmap.josm.tools.Base64;
     28import org.openstreetmap.josm.tools.GBC;
     29import org.openstreetmap.josm.tools.HttpClient;
     30import org.openstreetmap.josm.tools.HttpClient.Response;
     31import org.openstreetmap.josm.tools.OpenBrowser;
     32import org.openstreetmap.josm.tools.Utils;
     33import org.w3c.dom.Document;
     34import org.xml.sax.SAXException;
     35
     36/**
     37 * This class handles sending the bug report to JOSM website.
     38 * <p>
     39 * Currently, we try to open a browser window for the user that displays the bug report.
     40 *
     41 * @author Michael Zangl
     42 */
     43public class BugReportSender extends Thread {
     44
     45    private final String statusText;
     46
     47    /**
     48     * Creates a new sender.
     49     * @param statusText The status text to send.
     50     */
     51    public BugReportSender(String statusText) {
     52        super("Bug report sender");
     53        this.statusText = statusText;
     54    }
     55
     56    @Override
     57    public void run() {
     58        try {
     59            // first, send the debug text using post.
     60            String debugTextPasteId = pasteDebugText();
     61
     62            // then open a browser to display the pasted text.
     63            String openBrowserError = OpenBrowser.displayUrl(getJOSMTicketURL() + "?pdata_stored=" + debugTextPasteId);
     64            if (openBrowserError != null) {
     65                Main.warn(openBrowserError);
     66                failed(openBrowserError);
     67            }
     68        } catch (BugReportSenderException e) {
     69            Main.warn(e);
     70            failed(e.getMessage());
     71        }
     72    }
     73
     74    /**
     75     * Sends the debug text to the server.
     76     * @return The token which was returned by the server. We need to pass this on to the ticket system.
     77     * @throws BugReportSenderException if sending the report failed.
     78     */
     79    private String pasteDebugText() throws BugReportSenderException {
     80        try {
     81            String text = Utils.strip(statusText);
     82            String postQuery = "pdata=" + Base64.encode(text, true);
     83            HttpClient client = HttpClient.create(new URL(getJOSMTicketURL()), "POST")
     84                    .setHeader("Content-Type", "application/x-www-form-urlencoded")
     85                    .setRequestBody(postQuery.getBytes(StandardCharsets.UTF_8));
     86
     87            Response connection = client.connect();
     88
     89            try (InputStream in = connection.getContent()) {
     90                DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
     91                Document document = builder.parse(in);
     92                return retriveDebugToken(document);
     93            }
     94        } catch (IOException | SAXException | ParserConfigurationException | XPathExpressionException t) {
     95            throw new BugReportSenderException(t);
     96        }
     97    }
     98
     99    private String getJOSMTicketURL() {
     100        return Main.getJOSMWebsite() + "/josmticket";
     101    }
     102
     103    private String retriveDebugToken(Document document) throws XPathExpressionException, BugReportSenderException {
     104        XPathFactory factory = XPathFactory.newInstance();
     105        XPath xpath = factory.newXPath();
     106        String status = (String) xpath.compile("/josmticket/@status").evaluate(document, XPathConstants.STRING);
     107        if (!"ok".equals(status)) {
     108            String message = (String) xpath.compile("/josmticket/error/text()").evaluate(document,
     109                    XPathConstants.STRING);
     110            if (message.isEmpty()) {
     111                message = "Error in server response but server did not tell us what happened.";
     112            }
     113            throw new BugReportSenderException(message);
     114        }
     115
     116        String token = (String) xpath.compile("/josmticket/preparedid/text()")
     117                .evaluate(document, XPathConstants.STRING);
     118        if (token.isEmpty()) {
     119            throw new BugReportSenderException("Server did not respond with a prepared id.");
     120        }
     121        return token;
     122    }
     123
     124    private void failed(String string) {
     125        SwingUtilities.invokeLater(new Runnable() {
     126            @Override
     127            public void run() {
     128                JPanel errorPanel = new JPanel();
     129                errorPanel.setLayout(new GridBagLayout());
     130                errorPanel.add(new JMultilineLabel(
     131                        tr("Opening the bug report failed. Please report manually using this website:")),
     132                        GBC.eol().fill(GridBagConstraints.HORIZONTAL));
     133                errorPanel.add(new UrlLabel(Main.getJOSMWebsite() + "/newticket", 2), GBC.eop().insets(8, 0, 0, 0));
     134                errorPanel.add(new DebugTextDisplay(statusText));
     135
     136                JOptionPane.showMessageDialog(Main.parent, errorPanel, tr("You have encountered a bug in JOSM"),
     137                        JOptionPane.ERROR_MESSAGE);
     138            }
     139        });
     140    }
     141
     142    private static class BugReportSenderException extends Exception {
     143        BugReportSenderException(String message) {
     144            super(message);
     145        }
     146
     147        BugReportSenderException(Throwable cause) {
     148            super(cause);
     149        }
     150    }
     151
     152    /**
     153     * Opens the bug report window on the JOSM server.
     154     * @param statusText The status text to send along to the server.
     155     */
     156    public static void reportBug(String statusText) {
     157        new BugReportSender(statusText).start();
     158    }
     159}
  • new file src/org/openstreetmap/josm/tools/bugreport/DebugTextDisplay.java

    diff --git a/src/org/openstreetmap/josm/tools/bugreport/DebugTextDisplay.java b/src/org/openstreetmap/josm/tools/bugreport/DebugTextDisplay.java
    new file mode 100644
    index 0000000..12bbab6
    - +  
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.tools.bugreport;
     3
     4import java.awt.Dimension;
     5
     6import javax.swing.JScrollPane;
     7
     8import org.openstreetmap.josm.gui.widgets.JosmTextArea;
     9import org.openstreetmap.josm.tools.Utils;
     10
     11/**
     12 * This is a text area that displays the debug text with scroll bars.
     13 * @author Michael Zangl
     14 */
     15public class DebugTextDisplay extends JScrollPane {
     16    private String text;
     17
     18    /**
     19     * Creates a new text are with the fixed text
     20     * @param textToDisplay The text to display.
     21     */
     22    public DebugTextDisplay(String textToDisplay) {
     23        text = "{{{\n" + Utils.strip(textToDisplay) + "\n}}}";
     24        JosmTextArea textArea = new JosmTextArea(text);
     25        textArea.setCaretPosition(0);
     26        textArea.setEditable(false);
     27        setViewportView(textArea);
     28        setPreferredSize(new Dimension(600, 300));
     29    }
     30
     31    /**
     32     * Copies the debug text to the clippboard.
     33     * @return <code>true</code> if copy was successful
     34     */
     35    public boolean copyToClippboard() {
     36        return Utils.copyToClipboard(text);
     37    }
     38}