Ticket #12652: patch-bugreport-longer-error-message.patch
File patch-bugreport-longer-error-message.patch, 17.4 KB (added by , 9 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; 6 6 import java.awt.event.ActionEvent; 7 7 import java.awt.event.KeyEvent; 8 8 9 import org.openstreetmap.josm.tools.BugReportExceptionHandler;10 import org.openstreetmap.josm.tools.OpenBrowser;11 9 import org.openstreetmap.josm.tools.Shortcut; 12 import org.openstreetmap.josm.tools. Utils;10 import org.openstreetmap.josm.tools.bugreport.BugReportSender; 13 11 14 12 /** 15 13 * Reports a ticket to JOSM bugtracker. … … import org.openstreetmap.josm.tools.Utils; 17 15 */ 18 16 public class ReportBugAction extends JosmAction { 19 17 18 private final String text; 19 20 20 /** 21 * Constructs a new {@code ReportBugAction} .21 * Constructs a new {@code ReportBugAction} that reports the normal status report. 22 22 */ 23 23 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) { 24 32 super(tr("Report bug"), "bug", tr("Report a ticket to JOSM bugtracker"), 25 33 Shortcut.registerShortcut("reportbug", tr("Report a ticket to JOSM bugtracker"), 26 34 KeyEvent.CHAR_UNDEFINED, Shortcut.NONE), true); 35 this.text = text; 27 36 } 28 37 29 38 @Override 30 39 public void actionPerformed(ActionEvent e) { 31 reportBug();40 BugReportSender.reportBug(text); 32 41 } 33 42 34 43 /** 35 44 * Reports a ticket to JOSM bugtracker. 45 * @deprecated Use {@link BugReportSender#reportBug(String)} 36 46 */ 47 @Deprecated 37 48 public static void reportBug() { 38 reportBug(ShowStatusReportAction.getReportHeader());49 BugReportSender.reportBug(ShowStatusReportAction.getReportHeader()); 39 50 } 40 51 41 52 /** 42 53 * Reports a ticket to JOSM bugtracker with given status report. 54 * Replaced by {@link BugReportSender#reportBug(String)} 43 55 * @param report Status report header containing technical, non-personal information 56 * @deprecated Use {@link BugReportSender#reportBug(String)} 44 57 */ 58 @Deprecated 45 59 public static void reportBug(String report) { 46 OpenBrowser.displayUrl(BugReportExceptionHandler.getBugReportUrl( 47 Utils.strip(report)).toExternalForm()); 60 BugReportSender.reportBug(report); 48 61 } 49 62 } -
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; 19 19 import java.util.Map.Entry; 20 20 import java.util.Set; 21 21 22 import javax.swing.JScrollPane;23 24 22 import org.openstreetmap.josm.Main; 25 23 import org.openstreetmap.josm.data.Version; 26 24 import org.openstreetmap.josm.data.osm.DataSet; 27 25 import org.openstreetmap.josm.data.osm.DatasetConsistencyTest; 28 26 import org.openstreetmap.josm.data.preferences.Setting; 29 27 import org.openstreetmap.josm.gui.ExtendedDialog; 30 import org.openstreetmap.josm.gui.widgets.JosmTextArea;31 28 import org.openstreetmap.josm.plugins.PluginHandler; 32 29 import org.openstreetmap.josm.tools.PlatformHookUnixoid; 33 30 import org.openstreetmap.josm.tools.Shortcut; 34 import org.openstreetmap.josm.tools.Utils; 31 import org.openstreetmap.josm.tools.bugreport.BugReportSender; 32 import org.openstreetmap.josm.tools.bugreport.DebugTextDisplay; 35 33 36 34 /** 37 35 * @author xeen … … public final class ShowStatusReportAction extends JosmAction { 183 181 Main.error(x); 184 182 } 185 183 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()); 191 185 192 186 ExtendedDialog ed = new ExtendedDialog(Main.parent, 193 187 tr("Status Report"), 194 188 new String[] {tr("Copy to clipboard and close"), tr("Report bug"), tr("Close") }); 195 189 ed.setButtonIcons(new String[] {"copy", "bug", "cancel" }); 196 ed.setContent( sp, false);190 ed.setContent(ta, false); 197 191 ed.setMinimumSize(new Dimension(380, 200)); 198 192 ed.setPreferredSize(new Dimension(700, Main.parent.getHeight()-50)); 199 193 200 194 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; 203 197 } 204 198 } 205 199 } -
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; 15 15 import java.nio.charset.StandardCharsets; 16 16 import java.util.zip.GZIPOutputStream; 17 17 18 import javax.swing.JButton; 18 19 import javax.swing.JCheckBox; 19 20 import javax.swing.JLabel; 20 21 import javax.swing.JOptionPane; 21 22 import javax.swing.JPanel; 22 import javax.swing.JScrollPane;23 23 import javax.swing.SwingUtilities; 24 24 25 25 import org.openstreetmap.josm.Main; 26 import org.openstreetmap.josm.actions.ReportBugAction; 26 27 import org.openstreetmap.josm.actions.ShowStatusReportAction; 27 28 import org.openstreetmap.josm.data.Version; 28 29 import org.openstreetmap.josm.gui.ExtendedDialog; 29 30 import org.openstreetmap.josm.gui.preferences.plugin.PluginPreference; 30 31 import org.openstreetmap.josm.gui.widgets.JMultilineLabel; 31 import org.openstreetmap.josm.gui.widgets.JosmTextArea;32 32 import org.openstreetmap.josm.gui.widgets.UrlLabel; 33 33 import org.openstreetmap.josm.plugins.PluginDownloadTask; 34 34 import org.openstreetmap.josm.plugins.PluginHandler; 35 import org.openstreetmap.josm.tools.bugreport.BugReportSender; 36 import org.openstreetmap.josm.tools.bugreport.DebugTextDisplay; 35 37 36 38 /** 37 39 * An exception handler that asks the user to send a bug report. … … public final class BugReportExceptionHandler implements Thread.UncaughtException 193 195 194 196 private static void askForBugReport(final Throwable e) { 195 197 try { 196 final int maxlen = 6000;197 198 StringWriter stack = new StringWriter(); 198 199 e.printStackTrace(new PrintWriter(stack)); 199 200 200 201 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", ""); 211 203 212 204 JPanel p = new JPanel(new GridBagLayout()); 213 205 p.add(new JMultilineLabel( … … public final class BugReportExceptionHandler implements Thread.UncaughtException 219 211 tr("You should also update your plugins. If neither of those help please " + 220 212 "file a bug report in our bugtracker using this link:")), 221 213 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)); 223 215 p.add(new JMultilineLabel( 224 216 tr("There the error information provided below should already be " + 225 217 "filled in for you. Please include information on how to reproduce " + … … public final class BugReportExceptionHandler implements Thread.UncaughtException 231 223 p.add(new UrlLabel(Main.getJOSMWebsite()+"/newticket", 2), GBC.eop().insets(8, 0, 0, 0)); 232 224 233 225 // Wiki formatting for manual copy-paste 234 text = "{{{\n"+text+"}}}";226 DebugTextDisplay textarea = new DebugTextDisplay(text); 235 227 236 if ( Utils.copyToClipboard(text)) {228 if (textarea.copyToClippboard()) { 237 229 p.add(new JLabel(tr("(The text has already been copied to your clipboard.)")), 238 230 GBC.eop().fill(GridBagConstraints.HORIZONTAL)); 239 231 } 240 232 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()); 245 234 246 235 for (Component c: p.getComponents()) { 247 236 if (c instanceof JMultilineLabel) { … … public final class BugReportExceptionHandler implements Thread.UncaughtException 264 253 } 265 254 266 255 /** 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. 268 257 * @param debugText The debug text to provide us 269 258 * @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. 270 260 * @since 5849 271 261 */ 272 262 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. 2 package org.openstreetmap.josm.tools.bugreport; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 5 6 import java.awt.GridBagConstraints; 7 import java.awt.GridBagLayout; 8 import java.io.IOException; 9 import java.io.InputStream; 10 import java.net.URL; 11 import java.nio.charset.StandardCharsets; 12 13 import javax.swing.JOptionPane; 14 import javax.swing.JPanel; 15 import javax.swing.SwingUtilities; 16 import javax.xml.parsers.DocumentBuilder; 17 import javax.xml.parsers.DocumentBuilderFactory; 18 import javax.xml.parsers.ParserConfigurationException; 19 import javax.xml.xpath.XPath; 20 import javax.xml.xpath.XPathConstants; 21 import javax.xml.xpath.XPathExpressionException; 22 import javax.xml.xpath.XPathFactory; 23 24 import org.openstreetmap.josm.Main; 25 import org.openstreetmap.josm.gui.widgets.JMultilineLabel; 26 import org.openstreetmap.josm.gui.widgets.UrlLabel; 27 import org.openstreetmap.josm.tools.Base64; 28 import org.openstreetmap.josm.tools.GBC; 29 import org.openstreetmap.josm.tools.HttpClient; 30 import org.openstreetmap.josm.tools.HttpClient.Response; 31 import org.openstreetmap.josm.tools.OpenBrowser; 32 import org.openstreetmap.josm.tools.Utils; 33 import org.w3c.dom.Document; 34 import 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 */ 43 public 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. 2 package org.openstreetmap.josm.tools.bugreport; 3 4 import java.awt.Dimension; 5 6 import javax.swing.JScrollPane; 7 8 import org.openstreetmap.josm.gui.widgets.JosmTextArea; 9 import 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 */ 15 public 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 }