Ticket #3318: downloaderror.txt

File downloaderror.txt, 27.6 KB (added by dmuecke, 17 years ago)
Line 
1Index: src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
2===================================================================
3--- src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java (revision 2091)
4+++ src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java (working copy)
5@@ -16,7 +16,6 @@
6 import org.openstreetmap.josm.data.coor.LatLon;
7 import org.openstreetmap.josm.data.osm.DataSet;
8 import org.openstreetmap.josm.data.osm.DataSource;
9-import org.openstreetmap.josm.gui.ExceptionDialogUtil;
10 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
11 import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask;
12 import org.openstreetmap.josm.gui.layer.Layer;
13@@ -27,6 +26,7 @@
14 import org.openstreetmap.josm.io.OsmServerLocationReader;
15 import org.openstreetmap.josm.io.OsmServerReader;
16 import org.openstreetmap.josm.io.OsmTransferException;
17+import org.openstreetmap.josm.tools.ExceptionUtil;
18 import org.xml.sax.SAXException;
19
20
21@@ -106,15 +106,14 @@
22 if (canceled)
23 return;
24 if (lastException != null) {
25- ExceptionDialogUtil.explainException(lastException);
26+ getProgressMonitor().setErrorMessage(ExceptionUtil.explainException(lastException));
27 DownloadOsmTask.this.setFailed(true);
28 return;
29 }
30 if (dataSet == null)
31 return; // user canceled download or error occurred
32- if (currentBounds == null) {
33+ if (currentBounds == null)
34 return; // no data retrieved
35- }
36 if (dataSet.allPrimitives().isEmpty()) {
37 progressMonitor.setErrorMessage(tr("No data imported."));
38 // need to synthesize a download bounds lest the visual indication of downloaded
39Index: src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTaskList.java
40===================================================================
41--- src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTaskList.java (revision 2091)
42+++ src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTaskList.java (working copy)
43@@ -94,11 +94,14 @@
44 progressMonitor.finishTask();
45 String errors = "";
46
47+ LinkedList<Integer> shown = new LinkedList<Integer>();
48 for(DownloadTask dt : osmTasks) {
49 String err = dt.getErrorMessage();
50- if(err.equals("")) {
51+ // avoid display of identical messages
52+ if (err.equals("") || shown.contains(err.hashCode())) {
53 continue;
54 }
55+ shown.add(err.hashCode());
56 errors += "<br>* " + err;
57 }
58
59Index: src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java
60===================================================================
61--- src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java (revision 2091)
62+++ src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java (working copy)
63@@ -5,19 +5,17 @@
64
65 import java.io.IOException;
66 import java.net.HttpURLConnection;
67-import java.net.MalformedURLException;
68 import java.net.SocketException;
69-import java.net.URL;
70 import java.net.UnknownHostException;
71
72 import javax.swing.JOptionPane;
73
74 import org.openstreetmap.josm.Main;
75-import org.openstreetmap.josm.io.OsmApi;
76 import org.openstreetmap.josm.io.OsmApiException;
77 import org.openstreetmap.josm.io.OsmApiInitializationException;
78 import org.openstreetmap.josm.io.OsmChangesetCloseException;
79 import org.openstreetmap.josm.io.OsmTransferException;
80+import org.openstreetmap.josm.tools.ExceptionUtil;
81
82 /**
83 * This utility class provides static methods which explain various exceptions to the user.
84@@ -28,7 +26,8 @@
85 /**
86 * just static utility functions. no constructor
87 */
88- private ExceptionDialogUtil() {}
89+ private ExceptionDialogUtil() {
90+ }
91
92 /**
93 * handles an exception caught during OSM API initialization
94@@ -36,16 +35,8 @@
95 * @param e the exception
96 */
97 public static void explainOsmApiInitializationException(OsmApiInitializationException e) {
98- e.printStackTrace();
99- JOptionPane.showMessageDialog(
100- Main.parent,
101- tr( "<html>Failed to initialize communication with the OSM server {0}.<br>"
102- + "Check the server URL in your preferences and your internet connection.</html>",
103- Main.pref.get("osm-server.url", "http://api.openstreetmap.org/api")
104- ),
105- tr("Error"),
106- JOptionPane.ERROR_MESSAGE
107- );
108+ JOptionPane.showMessageDialog(Main.parent, ExceptionUtil.explainOsmApiInitializationException(e), tr("Error"),
109+ JOptionPane.ERROR_MESSAGE);
110 }
111
112 /**
113@@ -54,60 +45,28 @@
114 * @param e the exception
115 */
116 public static void explainOsmChangesetCloseException(OsmChangesetCloseException e) {
117- e.printStackTrace();
118- String changsetId = e.getChangeset() == null ? tr("unknown") : Long.toString(e.getChangeset().getId());
119- JOptionPane.showMessageDialog(
120- Main.parent,
121- tr( "<html>Failed to close changeset ''{0}'' on the OSM server ''{1}''.<br>"
122- + "The changeset will automatically be closed by the server after a timeout.</html>",
123- changsetId,
124- Main.pref.get("osm-server.url", "http://api.openstreetmap.org/api")
125- ),
126- tr("Error"),
127- JOptionPane.ERROR_MESSAGE
128- );
129+ JOptionPane.showMessageDialog(Main.parent, ExceptionUtil.explainOsmChangesetCloseException(e), tr("Error"),
130+ JOptionPane.ERROR_MESSAGE);
131 }
132
133-
134 /**
135 * Explains an upload error due to a violated precondition, i.e. a HTTP return code 412
136 *
137 * @param e the exception
138 */
139 public static void explainPreconditionFailed(OsmApiException e) {
140- e.printStackTrace();
141- JOptionPane.showMessageDialog(
142- Main.parent,
143- tr("<html>Uploading to the server <strong>failed</strong> because your current<br>"
144- +"dataset violates a precondition.<br>"
145- +"The error message is:<br>"
146- + "{0}"
147- + "</html>",
148- e.getMessage().replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
149- ),
150- tr("Precondition violation"),
151- JOptionPane.ERROR_MESSAGE
152- );
153+ JOptionPane.showMessageDialog(Main.parent, ExceptionUtil.explainPreconditionFailed(e),
154+ tr("Precondition violation"), JOptionPane.ERROR_MESSAGE);
155 }
156
157-
158 /**
159 * Explains an exception with a generic message dialog
160 *
161 * @param e the exception
162 */
163 public static void explainGeneric(Exception e) {
164- String msg = e.getMessage();
165- if (msg == null || msg.trim().equals("")) {
166- msg = e.toString();
167- }
168- e.printStackTrace();
169- JOptionPane.showMessageDialog(
170- Main.parent,
171- msg,
172- tr("Error"),
173- JOptionPane.ERROR_MESSAGE
174- );
175+ JOptionPane.showMessageDialog(Main.parent, ExceptionUtil.explainGeneric(e), tr("Error"),
176+ JOptionPane.ERROR_MESSAGE);
177 }
178
179 /**
180@@ -119,26 +78,8 @@
181 */
182
183 public static void explainSecurityException(OsmTransferException e) {
184- String apiUrl = OsmApi.getOsmApi().getBaseUrl();
185- String host = tr("unknown");
186- try {
187- host = new URL(apiUrl).getHost();
188- } catch(MalformedURLException ex) {
189- // shouldn't happen
190- }
191-
192- String message = tr("<html>Failed to open a connection to the remote server<br>"
193- + "''{0}''<br>"
194- + "for security reasons. This is most likely because you are running<br>"
195- + "in an applet and because you didn''t load your applet from ''{1}''.</html>",
196- apiUrl, host
197- );
198- JOptionPane.showMessageDialog(
199- Main.parent,
200- message,
201- tr("Security exception"),
202- JOptionPane.ERROR_MESSAGE
203- );
204+ JOptionPane.showMessageDialog(Main.parent, ExceptionUtil.explainSecurityException(e), tr("Security exception"),
205+ JOptionPane.ERROR_MESSAGE);
206 }
207
208 /**
209@@ -150,19 +91,8 @@
210 */
211
212 public static void explainNestedSocketException(OsmTransferException e) {
213- String apiUrl = OsmApi.getOsmApi().getBaseUrl();
214- String message = tr("<html>Failed to open a connection to the remote server<br>"
215- + "''{0}''.<br>"
216- + "Please check your internet connection.</html>",
217- apiUrl
218- );
219- e.printStackTrace();
220- JOptionPane.showMessageDialog(
221- Main.parent,
222- message,
223- tr("Network exception"),
224- JOptionPane.ERROR_MESSAGE
225- );
226+ JOptionPane.showMessageDialog(Main.parent, ExceptionUtil.explainNestedSocketException(e),
227+ tr("Network exception"), JOptionPane.ERROR_MESSAGE);
228 }
229
230 /**
231@@ -174,21 +104,8 @@
232 */
233
234 public static void explainNestedIOException(OsmTransferException e) {
235- IOException ioe = getNestedException(e, IOException.class);
236- String apiUrl = OsmApi.getOsmApi().getBaseUrl();
237- String message = tr("<html>Failed to upload data to or download data from<br>"
238- + "''{0}''<br>"
239- + "due to a problem with transferring data.<br>"
240- + "Details(untranslated): {1}</html>",
241- apiUrl, ioe.getMessage()
242- );
243- e.printStackTrace();
244- JOptionPane.showMessageDialog(
245- Main.parent,
246- message,
247- tr("IO Exception"),
248- JOptionPane.ERROR_MESSAGE
249- );
250+ JOptionPane.showMessageDialog(Main.parent, ExceptionUtil.explainNestedIOException(e), tr("IO Exception"),
251+ JOptionPane.ERROR_MESSAGE);
252 }
253
254 /**
255@@ -199,20 +116,8 @@
256 */
257
258 public static void explainInternalServerError(OsmTransferException e) {
259- String apiUrl = OsmApi.getOsmApi().getBaseUrl();
260- String message = tr("<html>The OSM server<br>"
261- + "''{0}''<br>"
262- + "reported an internal server error.<br>"
263- + "This is most likely a temporary problem. Please try again later.</html>",
264- apiUrl
265- );
266- e.printStackTrace();
267- JOptionPane.showMessageDialog(
268- Main.parent,
269- message,
270- tr("Internal Server Error"),
271- JOptionPane.ERROR_MESSAGE
272- );
273+ JOptionPane.showMessageDialog(Main.parent, ExceptionUtil.explainInternalServerError(e),
274+ tr("Internal Server Error"), JOptionPane.ERROR_MESSAGE);
275 }
276
277 /**
278@@ -222,24 +127,8 @@
279 * @param e the exception
280 */
281 public static void explainBadRequest(OsmApiException e) {
282- String apiUrl = OsmApi.getOsmApi().getBaseUrl();
283- String message = tr("The OSM server ''{0}'' reported a bad request.<br>",
284- apiUrl
285- );
286- if (e.getErrorHeader() != null && e.getErrorHeader().startsWith("The maximum bbox")) {
287- message += "<br>" + tr("The area you tried to download is too big or your request was too large."
288- + "<br>Either request a smaller area or use an export file provided by the OSM community.");
289- } else if (e.getErrorHeader() != null){
290- message += tr("<br>Error message(untranslated): {0}", e.getErrorHeader());
291- }
292- message = "<html>" + message + "</html>";
293- e.printStackTrace();
294- JOptionPane.showMessageDialog(
295- Main.parent,
296- message,
297- tr("Bad Request"),
298- JOptionPane.ERROR_MESSAGE
299- );
300+ JOptionPane.showMessageDialog(Main.parent, ExceptionUtil.explainBadRequest(e), tr("Bad Request"),
301+ JOptionPane.ERROR_MESSAGE);
302 }
303
304 /**
305@@ -251,27 +140,8 @@
306 */
307
308 public static void explainNestedUnkonwnHostException(OsmTransferException e) {
309- String apiUrl = OsmApi.getOsmApi().getBaseUrl();
310- String host = tr("unknown");
311- try {
312- host = new URL(apiUrl).getHost();
313- } catch(MalformedURLException ex) {
314- // shouldn't happen
315- }
316-
317- String message = tr("<html>Failed to open a connection to the remote server<br>"
318- + "''{0}''.<br>"
319- + "Host name ''{1}'' couldn''t be resolved. <br>"
320- + "Please check the API URL in your preferences and your internet connection.</html>",
321- apiUrl, host
322- );
323- e.printStackTrace();
324- JOptionPane.showMessageDialog(
325- Main.parent,
326- message,
327- tr("Unknown host"),
328- JOptionPane.ERROR_MESSAGE
329- );
330+ JOptionPane.showMessageDialog(Main.parent, ExceptionUtil.explainNestedUnkonwnHostException(e),
331+ tr("Unknown host"), JOptionPane.ERROR_MESSAGE);
332 }
333
334 /**
335@@ -289,7 +159,7 @@
336 while (t != null && !(nestedClass.isInstance(t))) {
337 t = t.getCause();
338 }
339- if (t== null)
340+ if (t == null)
341 return null;
342 else if (nestedClass.isInstance(t))
343 return nestedClass.cast(t);
344@@ -318,17 +188,17 @@
345 explainNestedIOException(e);
346 return;
347 }
348- if (e instanceof OsmApiInitializationException){
349- explainOsmApiInitializationException((OsmApiInitializationException)e);
350+ if (e instanceof OsmApiInitializationException) {
351+ explainOsmApiInitializationException((OsmApiInitializationException) e);
352 return;
353 }
354- if (e instanceof OsmChangesetCloseException){
355- explainOsmChangesetCloseException((OsmChangesetCloseException)e);
356+ if (e instanceof OsmChangesetCloseException) {
357+ explainOsmChangesetCloseException((OsmChangesetCloseException) e);
358 return;
359 }
360
361 if (e instanceof OsmApiException) {
362- OsmApiException oae = (OsmApiException)e;
363+ OsmApiException oae = (OsmApiException) e;
364 if (oae.getResponseCode() == HttpURLConnection.HTTP_PRECON_FAILED) {
365 explainPreconditionFailed(oae);
366 return;
367@@ -357,20 +227,8 @@
368 * @param e the exception
369 */
370 public static void explainGoneForUnknownPrimitive(OsmApiException e) {
371- String msg = tr("<html>Uploading <strong>failed</strong> because a primitive you tried to<br>"
372- + "delete on the server is already deleted.<br>"
373- + "<br>"
374- + "The error message is:<br>"
375- + "{0}"
376- + "</html>",
377- e.getMessage().replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
378- );
379- JOptionPane.showMessageDialog(
380- Main.parent,
381- msg,
382- tr("Primitive already deleted"),
383- JOptionPane.ERROR_MESSAGE
384- );
385+ JOptionPane.showMessageDialog(Main.parent, ExceptionUtil.explainGoneForUnknownPrimitive(e),
386+ tr("Primitive already deleted"), JOptionPane.ERROR_MESSAGE);
387
388 }
389
390@@ -381,7 +239,7 @@
391 */
392 public static void explainException(Exception e) {
393 if (e instanceof OsmTransferException) {
394- explainOsmTransferException((OsmTransferException)e);
395+ explainOsmTransferException((OsmTransferException) e);
396 return;
397 }
398 explainGeneric(e);
399Index: src/org/openstreetmap/josm/tools/ExceptionUtil.java
400===================================================================
401--- src/org/openstreetmap/josm/tools/ExceptionUtil.java (revision 0)
402+++ src/org/openstreetmap/josm/tools/ExceptionUtil.java (revision 0)
403@@ -0,0 +1,279 @@
404+// License: GPL. For details, see LICENSE file.
405+package org.openstreetmap.josm.tools;
406+
407+import static org.openstreetmap.josm.tools.I18n.tr;
408+
409+import java.io.IOException;
410+import java.net.HttpURLConnection;
411+import java.net.MalformedURLException;
412+import java.net.SocketException;
413+import java.net.URL;
414+import java.net.UnknownHostException;
415+
416+import org.openstreetmap.josm.Main;
417+import org.openstreetmap.josm.io.OsmApi;
418+import org.openstreetmap.josm.io.OsmApiException;
419+import org.openstreetmap.josm.io.OsmApiInitializationException;
420+import org.openstreetmap.josm.io.OsmChangesetCloseException;
421+import org.openstreetmap.josm.io.OsmTransferException;
422+
423+public class ExceptionUtil {
424+ private ExceptionUtil() {
425+ }
426+
427+ /**
428+ * handles an exception caught during OSM API initialization
429+ *
430+ * @param e the exception
431+ */
432+ public static String explainOsmApiInitializationException(OsmApiInitializationException e) {
433+ e.printStackTrace();
434+ String msg = tr(
435+ "<html>Failed to initialize communication with the OSM server {0}.<br>"
436+ + "Check the server URL in your preferences and your internet connection.</html>", Main.pref.get(
437+ "osm-server.url", "http://api.openstreetmap.org/api"));
438+ return msg;
439+ }
440+
441+ /**
442+ * handles an exception caught during OSM API initialization
443+ *
444+ * @param e the exception
445+ */
446+ public static String explainOsmChangesetCloseException(OsmChangesetCloseException e) {
447+ e.printStackTrace();
448+ String changsetId = e.getChangeset() == null ? tr("unknown") : Long.toString(e.getChangeset().getId());
449+ String msg = tr(
450+ "<html>Failed to close changeset ''{0}'' on the OSM server ''{1}''.<br>"
451+ + "The changeset will automatically be closed by the server after a timeout.</html>", changsetId,
452+ Main.pref.get("osm-server.url", "http://api.openstreetmap.org/api"));
453+ return msg;
454+ }
455+
456+
457+ /**
458+ * Explains an upload error due to a violated precondition, i.e. a HTTP return code 412
459+ *
460+ * @param e the exception
461+ */
462+ public static String explainPreconditionFailed(OsmApiException e) {
463+ e.printStackTrace();
464+ String msg = tr(
465+ "<html>Uploading to the server <strong>failed</strong> because your current<br>"
466+ + "dataset violates a precondition.<br>" + "The error message is:<br>" + "{0}" + "</html>", e
467+ .getMessage().replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;"));
468+ return msg;
469+ }
470+
471+ /**
472+ * Explains an exception with a generic message dialog
473+ *
474+ * @param e the exception
475+ */
476+ public static String explainGeneric(Exception e) {
477+ String msg = e.getMessage();
478+ if (msg == null || msg.trim().equals("")) {
479+ msg = e.toString();
480+ }
481+ e.printStackTrace();
482+ return msg;
483+ }
484+
485+ /**
486+ * Explains a {@see SecurityException} which has caused an {@see OsmTransferException}.
487+ * This is most likely happening when user tries to access the OSM API from within an
488+ * applet which wasn't loaded from the API server.
489+ *
490+ * @param e the exception
491+ */
492+
493+ public static String explainSecurityException(OsmTransferException e) {
494+ String apiUrl = OsmApi.getOsmApi().getBaseUrl();
495+ String host = tr("unknown");
496+ try {
497+ host = new URL(apiUrl).getHost();
498+ } catch (MalformedURLException ex) {
499+ // shouldn't happen
500+ }
501+
502+ String message = tr("<html>Failed to open a connection to the remote server<br>" + "''{0}''<br>"
503+ + "for security reasons. This is most likely because you are running<br>"
504+ + "in an applet and because you didn''t load your applet from ''{1}''.</html>", apiUrl, host);
505+ return message;
506+ }
507+
508+ /**
509+ * Explains a {@see SocketException} which has caused an {@see OsmTransferException}.
510+ * This is most likely because there's not connection to the Internet or because
511+ * the remote server is not reachable.
512+ *
513+ * @param e the exception
514+ */
515+
516+ public static String explainNestedSocketException(OsmTransferException e) {
517+ String apiUrl = OsmApi.getOsmApi().getBaseUrl();
518+ String message = tr("<html>Failed to open a connection to the remote server<br>" + "''{0}''.<br>"
519+ + "Please check your internet connection.</html>", apiUrl);
520+ e.printStackTrace();
521+ return message;
522+ }
523+
524+ /**
525+ * Explains a {@see IOException} which has caused an {@see OsmTransferException}.
526+ * This is most likely happening when the communication with the remote server is
527+ * interrupted for any reason.
528+ *
529+ * @param e the exception
530+ */
531+
532+ public static String explainNestedIOException(OsmTransferException e) {
533+ IOException ioe = getNestedException(e, IOException.class);
534+ String apiUrl = OsmApi.getOsmApi().getBaseUrl();
535+ String message = tr("<html>Failed to upload data to or download data from<br>" + "''{0}''<br>"
536+ + "due to a problem with transferring data.<br>" + "Details(untranslated): {1}</html>", apiUrl, ioe
537+ .getMessage());
538+ e.printStackTrace();
539+ return message;
540+ }
541+
542+ /**
543+ * Explains a {@see OsmApiException} which was thrown because of an internal server
544+ * error in the OSM API server..
545+ *
546+ * @param e the exception
547+ */
548+
549+ public static String explainInternalServerError(OsmTransferException e) {
550+ String apiUrl = OsmApi.getOsmApi().getBaseUrl();
551+ String message = tr("<html>The OSM server<br>" + "''{0}''<br>" + "reported an internal server error.<br>"
552+ + "This is most likely a temporary problem. Please try again later.</html>", apiUrl);
553+ e.printStackTrace();
554+ return message;
555+ }
556+
557+ /**
558+ * Explains a {@see OsmApiException} which was thrown because of a bad
559+ * request
560+ *
561+ * @param e the exception
562+ */
563+ public static String explainBadRequest(OsmApiException e) {
564+ String apiUrl = OsmApi.getOsmApi().getBaseUrl();
565+ String message = tr("The OSM server ''{0}'' reported a bad request.<br>", apiUrl);
566+ if (e.getErrorHeader() != null && e.getErrorHeader().startsWith("The maximum bbox")) {
567+ message += "<br>"
568+ + tr("The area you tried to download is too big or your request was too large."
569+ + "<br>Either request a smaller area or use an export file provided by the OSM community.");
570+ } else if (e.getErrorHeader() != null) {
571+ message += tr("<br>Error message(untranslated): {0}", e.getErrorHeader());
572+ }
573+ message = "<html>" + message + "</html>";
574+ e.printStackTrace();
575+ return message;
576+ }
577+
578+ /**
579+ * Explains a {@see UnknownHostException} which has caused an {@see OsmTransferException}.
580+ * This is most likely happening when there is an error in the API URL or when
581+ * local DNS services are not working.
582+ *
583+ * @param e the exception
584+ */
585+
586+ public static String explainNestedUnkonwnHostException(OsmTransferException e) {
587+ String apiUrl = OsmApi.getOsmApi().getBaseUrl();
588+ String host = tr("unknown");
589+ try {
590+ host = new URL(apiUrl).getHost();
591+ } catch (MalformedURLException ex) {
592+ // shouldn't happen
593+ }
594+
595+ String message = tr("<html>Failed to open a connection to the remote server<br>" + "''{0}''.<br>"
596+ + "Host name ''{1}'' couldn''t be resolved. <br>"
597+ + "Please check the API URL in your preferences and your internet connection.</html>", apiUrl, host);
598+ e.printStackTrace();
599+ return message;
600+ }
601+
602+ /**
603+ * Replies the first nested exception of type <code>nestedClass</code> (including
604+ * the root exception <code>e</code>) or null, if no such exception is found.
605+ *
606+ * @param <T>
607+ * @param e the root exception
608+ * @param nestedClass the type of the nested exception
609+ * @return the first nested exception of type <code>nestedClass</code> (including
610+ * the root exception <code>e</code>) or null, if no such exception is found.
611+ */
612+ protected static <T> T getNestedException(Exception e, Class<T> nestedClass) {
613+ Throwable t = e;
614+ while (t != null && !(nestedClass.isInstance(t))) {
615+ t = t.getCause();
616+ }
617+ if (t == null)
618+ return null;
619+ else if (nestedClass.isInstance(t))
620+ return nestedClass.cast(t);
621+ return null;
622+ }
623+
624+ /**
625+ * Explains an {@see OsmTransferException} to the user.
626+ *
627+ * @param e the {@see OsmTransferException}
628+ */
629+ public static String explainOsmTransferException(OsmTransferException e) {
630+ if (getNestedException(e, SecurityException.class) != null)
631+ return explainSecurityException(e);
632+ if (getNestedException(e, SocketException.class) != null)
633+ return explainNestedSocketException(e);
634+ if (getNestedException(e, UnknownHostException.class) != null)
635+ return explainNestedUnkonwnHostException(e);
636+ if (getNestedException(e, IOException.class) != null)
637+ return explainNestedIOException(e);
638+ if (e instanceof OsmApiInitializationException)
639+ return explainOsmApiInitializationException((OsmApiInitializationException) e);
640+ if (e instanceof OsmChangesetCloseException)
641+ return explainOsmChangesetCloseException((OsmChangesetCloseException) e);
642+
643+ if (e instanceof OsmApiException) {
644+ OsmApiException oae = (OsmApiException) e;
645+ if (oae.getResponseCode() == HttpURLConnection.HTTP_PRECON_FAILED)
646+ return explainPreconditionFailed(oae);
647+ if (oae.getResponseCode() == HttpURLConnection.HTTP_GONE)
648+ return explainGoneForUnknownPrimitive(oae);
649+ if (oae.getResponseCode() == HttpURLConnection.HTTP_INTERNAL_ERROR)
650+ return explainInternalServerError(oae);
651+ if (oae.getResponseCode() == HttpURLConnection.HTTP_BAD_REQUEST)
652+ return explainBadRequest(oae);
653+ }
654+ return explainGeneric(e);
655+ }
656+
657+ /**
658+ * explains the case of an error due to a delete request on an already deleted
659+ * {@see OsmPrimitive}, i.e. a HTTP response code 410, where we don't know which
660+ * {@see OsmPrimitive} is causing the error.
661+ *
662+ * @param e the exception
663+ */
664+ public static String explainGoneForUnknownPrimitive(OsmApiException e) {
665+ String msg = tr("<html>Uploading <strong>failed</strong> because a primitive you tried to<br>"
666+ + "delete on the server is already deleted.<br>" + "<br>" + "The error message is:<br>" + "{0}"
667+ + "</html>", e.getMessage().replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;"));
668+ return msg;
669+
670+ }
671+
672+ /**
673+ * Explains an {@see Exception} to the user.
674+ *
675+ * @param e the {@see Exception}
676+ */
677+ public static String explainException(Exception e) {
678+ if (e instanceof OsmTransferException)
679+ return explainOsmTransferException((OsmTransferException) e);
680+ return explainGeneric(e);
681+ }
682+}