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