source: josm/trunk/src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java@ 10101

Last change on this file since 10101 was 10055, checked in by Don-vip, 8 years ago

fix #12652 - Do not ...snip... bug report messages after 6000 characters (patch by michael2402, modified)

  • Property svn:eol-style set to native
File size: 17.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.io.IOException;
8import java.lang.reflect.InvocationTargetException;
9import java.net.HttpURLConnection;
10import java.net.SocketException;
11import java.net.UnknownHostException;
12import java.util.regex.Matcher;
13import java.util.regex.Pattern;
14
15import javax.swing.JOptionPane;
16
17import org.openstreetmap.josm.Main;
18import org.openstreetmap.josm.data.osm.OsmPrimitive;
19import org.openstreetmap.josm.io.ChangesetClosedException;
20import org.openstreetmap.josm.io.IllegalDataException;
21import org.openstreetmap.josm.io.MissingOAuthAccessTokenException;
22import org.openstreetmap.josm.io.OfflineAccessException;
23import org.openstreetmap.josm.io.OsmApi;
24import org.openstreetmap.josm.io.OsmApiException;
25import org.openstreetmap.josm.io.OsmApiInitializationException;
26import org.openstreetmap.josm.io.OsmTransferException;
27import org.openstreetmap.josm.tools.ExceptionUtil;
28import org.openstreetmap.josm.tools.bugreport.BugReportExceptionHandler;
29
30/**
31 * This utility class provides static methods which explain various exceptions to the user.
32 *
33 */
34public final class ExceptionDialogUtil {
35
36 /**
37 * just static utility functions. no constructor
38 */
39 private ExceptionDialogUtil() {
40 }
41
42 /**
43 * handles an exception caught during OSM API initialization
44 *
45 * @param e the exception
46 */
47 public static void explainOsmApiInitializationException(OsmApiInitializationException e) {
48 HelpAwareOptionPane.showOptionDialog(
49 Main.parent,
50 ExceptionUtil.explainOsmApiInitializationException(e),
51 tr("Error"),
52 JOptionPane.ERROR_MESSAGE,
53 ht("/ErrorMessages#OsmApiInitializationException")
54 );
55 }
56
57 /**
58 * handles a ChangesetClosedException
59 *
60 * @param e the exception
61 */
62 public static void explainChangesetClosedException(ChangesetClosedException e) {
63 HelpAwareOptionPane.showOptionDialog(
64 Main.parent,
65 ExceptionUtil.explainChangesetClosedException(e),
66 tr("Error"),
67 JOptionPane.ERROR_MESSAGE,
68 ht("/Action/Upload#ChangesetClosed")
69 );
70 }
71
72 /**
73 * Explains an upload error due to a violated precondition, i.e. a HTTP return code 412
74 *
75 * @param e the exception
76 */
77 public static void explainPreconditionFailed(OsmApiException e) {
78 HelpAwareOptionPane.showOptionDialog(
79 Main.parent,
80 ExceptionUtil.explainPreconditionFailed(e),
81 tr("Precondition violation"),
82 JOptionPane.ERROR_MESSAGE,
83 ht("/ErrorMessages#OsmApiException")
84 );
85 }
86
87 /**
88 * Explains an exception with a generic message dialog
89 *
90 * @param e the exception
91 */
92 public static void explainGeneric(Exception e) {
93 Main.error(e);
94 BugReportExceptionHandler.handleException(e);
95 }
96
97 /**
98 * Explains a {@link SecurityException} which has caused an {@link OsmTransferException}.
99 * This is most likely happening when user tries to access the OSM API from within an
100 * applet which wasn't loaded from the API server.
101 *
102 * @param e the exception
103 */
104
105 public static void explainSecurityException(OsmTransferException e) {
106 HelpAwareOptionPane.showOptionDialog(
107 Main.parent,
108 ExceptionUtil.explainSecurityException(e),
109 tr("Security exception"),
110 JOptionPane.ERROR_MESSAGE,
111 ht("/ErrorMessages#SecurityException")
112 );
113 }
114
115 /**
116 * Explains a {@link SocketException} which has caused an {@link OsmTransferException}.
117 * This is most likely because there's not connection to the Internet or because
118 * the remote server is not reachable.
119 *
120 * @param e the exception
121 */
122
123 public static void explainNestedSocketException(OsmTransferException e) {
124 HelpAwareOptionPane.showOptionDialog(
125 Main.parent,
126 ExceptionUtil.explainNestedSocketException(e),
127 tr("Network exception"),
128 JOptionPane.ERROR_MESSAGE,
129 ht("/ErrorMessages#NestedSocketException")
130 );
131 }
132
133 /**
134 * Explains a {@link IOException} which has caused an {@link OsmTransferException}.
135 * This is most likely happening when the communication with the remote server is
136 * interrupted for any reason.
137 *
138 * @param e the exception
139 */
140
141 public static void explainNestedIOException(OsmTransferException e) {
142 HelpAwareOptionPane.showOptionDialog(
143 Main.parent,
144 ExceptionUtil.explainNestedIOException(e),
145 tr("IO Exception"),
146 JOptionPane.ERROR_MESSAGE,
147 ht("/ErrorMessages#NestedIOException")
148 );
149 }
150
151 /**
152 * Explains a {@link IllegalDataException} which has caused an {@link OsmTransferException}.
153 * This is most likely happening when JOSM tries to load data in an unsupported format.
154 *
155 * @param e the exception
156 */
157 public static void explainNestedIllegalDataException(OsmTransferException e) {
158 HelpAwareOptionPane.showOptionDialog(
159 Main.parent,
160 ExceptionUtil.explainNestedIllegalDataException(e),
161 tr("Illegal Data"),
162 JOptionPane.ERROR_MESSAGE,
163 ht("/ErrorMessages#IllegalDataException")
164 );
165 }
166
167 /**
168 * Explains a {@link OfflineAccessException} which has caused an {@link OsmTransferException}.
169 * This is most likely happening when JOSM tries to access OSM API or JOSM website while in offline mode.
170 *
171 * @param e the exception
172 * @since 7434
173 */
174 public static void explainNestedOfflineAccessException(OsmTransferException e) {
175 HelpAwareOptionPane.showOptionDialog(
176 Main.parent,
177 ExceptionUtil.explainOfflineAccessException(e),
178 tr("Offline mode"),
179 JOptionPane.ERROR_MESSAGE,
180 ht("/ErrorMessages#OfflineAccessException")
181 );
182 }
183
184 /**
185 * Explains a {@link InvocationTargetException }
186 *
187 * @param e the exception
188 */
189 public static void explainNestedInvocationTargetException(Exception e) {
190 InvocationTargetException ex = ExceptionUtil.getNestedException(e, InvocationTargetException.class);
191 if (ex != null) {
192 // Users should be able to submit a bug report for an invocation target exception
193 //
194 BugReportExceptionHandler.handleException(ex);
195 return;
196 }
197 }
198
199 /**
200 * Explains a {@link OsmApiException} which was thrown because of an internal server
201 * error in the OSM API server.
202 *
203 * @param e the exception
204 */
205
206 public static void explainInternalServerError(OsmTransferException e) {
207 HelpAwareOptionPane.showOptionDialog(
208 Main.parent,
209 ExceptionUtil.explainInternalServerError(e),
210 tr("Internal Server Error"),
211 JOptionPane.ERROR_MESSAGE,
212 ht("/ErrorMessages#InternalServerError")
213 );
214 }
215
216 /**
217 * Explains a {@link OsmApiException} which was thrown because of a bad
218 * request
219 *
220 * @param e the exception
221 */
222 public static void explainBadRequest(OsmApiException e) {
223 HelpAwareOptionPane.showOptionDialog(
224 Main.parent,
225 ExceptionUtil.explainBadRequest(e),
226 tr("Bad Request"),
227 JOptionPane.ERROR_MESSAGE,
228 ht("/ErrorMessages#BadRequest")
229 );
230 }
231
232 /**
233 * Explains a {@link OsmApiException} which was thrown because a resource wasn't found
234 * on the server
235 *
236 * @param e the exception
237 */
238 public static void explainNotFound(OsmApiException e) {
239 HelpAwareOptionPane.showOptionDialog(
240 Main.parent,
241 ExceptionUtil.explainNotFound(e),
242 tr("Not Found"),
243 JOptionPane.ERROR_MESSAGE,
244 ht("/ErrorMessages#NotFound")
245 );
246 }
247
248 /**
249 * Explains a {@link OsmApiException} which was thrown because of a conflict
250 *
251 * @param e the exception
252 */
253 public static void explainConflict(OsmApiException e) {
254 HelpAwareOptionPane.showOptionDialog(
255 Main.parent,
256 ExceptionUtil.explainConflict(e),
257 tr("Conflict"),
258 JOptionPane.ERROR_MESSAGE,
259 ht("/ErrorMessages#Conflict")
260 );
261 }
262
263 /**
264 * Explains a {@link OsmApiException} which was thrown because the authentication at
265 * the OSM server failed
266 *
267 * @param e the exception
268 */
269 public static void explainAuthenticationFailed(OsmApiException e) {
270 String msg;
271 if (OsmApi.isUsingOAuth()) {
272 msg = ExceptionUtil.explainFailedOAuthAuthentication(e);
273 } else {
274 msg = ExceptionUtil.explainFailedBasicAuthentication(e);
275 }
276
277 HelpAwareOptionPane.showOptionDialog(
278 Main.parent,
279 msg,
280 tr("Authentication Failed"),
281 JOptionPane.ERROR_MESSAGE,
282 ht("/ErrorMessages#AuthenticationFailed")
283 );
284 }
285
286 /**
287 * Explains a {@link OsmApiException} which was thrown because accessing a protected
288 * resource was forbidden (HTTP 403).
289 *
290 * @param e the exception
291 */
292 public static void explainAuthorizationFailed(OsmApiException e) {
293
294 Matcher m;
295 String msg;
296 String url = e.getAccessedUrl();
297 Pattern p = Pattern.compile("https?://.*/api/0.6/(node|way|relation)/(\\d+)/(\\d+)");
298
299 // Special case for individual access to redacted versions
300 // See http://wiki.openstreetmap.org/wiki/Open_Database_License/Changes_in_the_API
301 if (url != null && (m = p.matcher(url)).matches()) {
302 String type = m.group(1);
303 String id = m.group(2);
304 String version = m.group(3);
305 // {1} is the translation of "node", "way" or "relation"
306 msg = tr("Access to redacted version ''{0}'' of {1} {2} is forbidden.",
307 version, tr(type), id);
308 } else if (OsmApi.isUsingOAuth()) {
309 msg = ExceptionUtil.explainFailedOAuthAuthorisation(e);
310 } else {
311 msg = ExceptionUtil.explainFailedAuthorisation(e);
312 }
313
314 HelpAwareOptionPane.showOptionDialog(
315 Main.parent,
316 msg,
317 tr("Authorisation Failed"),
318 JOptionPane.ERROR_MESSAGE,
319 ht("/ErrorMessages#AuthorizationFailed")
320 );
321 }
322
323 /**
324 * Explains a {@link OsmApiException} which was thrown because of a
325 * client timeout (HTTP 408)
326 *
327 * @param e the exception
328 */
329 public static void explainClientTimeout(OsmApiException e) {
330 HelpAwareOptionPane.showOptionDialog(
331 Main.parent,
332 ExceptionUtil.explainClientTimeout(e),
333 tr("Client Time Out"),
334 JOptionPane.ERROR_MESSAGE,
335 ht("/ErrorMessages#ClientTimeOut")
336 );
337 }
338
339 /**
340 * Explains a {@link OsmApiException} which was thrown because of a
341 * bandwidth limit (HTTP 509)
342 *
343 * @param e the exception
344 */
345 public static void explainBandwidthLimitExceeded(OsmApiException e) {
346 HelpAwareOptionPane.showOptionDialog(
347 Main.parent,
348 ExceptionUtil.explainBandwidthLimitExceeded(e),
349 tr("Bandwidth Limit Exceeded"),
350 JOptionPane.ERROR_MESSAGE,
351 ht("/ErrorMessages#BandwidthLimit")
352 );
353 }
354
355 /**
356 * Explains a {@link OsmApiException} with a generic error message.
357 *
358 * @param e the exception
359 */
360 public static void explainGenericHttpException(OsmApiException e) {
361 HelpAwareOptionPane.showOptionDialog(
362 Main.parent,
363 ExceptionUtil.explainClientTimeout(e),
364 tr("Communication with OSM server failed"),
365 JOptionPane.ERROR_MESSAGE,
366 ht("/ErrorMessages#GenericCommunicationError")
367 );
368 }
369
370 /**
371 * Explains a {@link OsmApiException} which was thrown because accessing a protected
372 * resource was forbidden.
373 *
374 * @param e the exception
375 */
376 public static void explainMissingOAuthAccessTokenException(MissingOAuthAccessTokenException e) {
377 HelpAwareOptionPane.showOptionDialog(
378 Main.parent,
379 ExceptionUtil.explainMissingOAuthAccessTokenException(e),
380 tr("Authentication failed"),
381 JOptionPane.ERROR_MESSAGE,
382 ht("/ErrorMessages#MissingOAuthAccessToken")
383 );
384 }
385
386 /**
387 * Explains a {@link UnknownHostException} which has caused an {@link OsmTransferException}.
388 * This is most likely happening when there is an error in the API URL or when
389 * local DNS services are not working.
390 *
391 * @param e the exception
392 */
393 public static void explainNestedUnkonwnHostException(OsmTransferException e) {
394 HelpAwareOptionPane.showOptionDialog(
395 Main.parent,
396 ExceptionUtil.explainNestedUnknownHostException(e),
397 tr("Unknown host"),
398 JOptionPane.ERROR_MESSAGE,
399 ht("/ErrorMessages#UnknownHost")
400 );
401 }
402
403 /**
404 * Explains an {@link OsmTransferException} to the user.
405 *
406 * @param e the {@link OsmTransferException}
407 */
408 public static void explainOsmTransferException(OsmTransferException e) {
409 if (ExceptionUtil.getNestedException(e, SecurityException.class) != null) {
410 explainSecurityException(e);
411 return;
412 }
413 if (ExceptionUtil.getNestedException(e, SocketException.class) != null) {
414 explainNestedSocketException(e);
415 return;
416 }
417 if (ExceptionUtil.getNestedException(e, UnknownHostException.class) != null) {
418 explainNestedUnkonwnHostException(e);
419 return;
420 }
421 if (ExceptionUtil.getNestedException(e, IOException.class) != null) {
422 explainNestedIOException(e);
423 return;
424 }
425 if (ExceptionUtil.getNestedException(e, IllegalDataException.class) != null) {
426 explainNestedIllegalDataException(e);
427 return;
428 }
429 if (ExceptionUtil.getNestedException(e, OfflineAccessException.class) != null) {
430 explainNestedOfflineAccessException(e);
431 return;
432 }
433 if (e instanceof OsmApiInitializationException) {
434 explainOsmApiInitializationException((OsmApiInitializationException) e);
435 return;
436 }
437
438 if (e instanceof ChangesetClosedException) {
439 explainChangesetClosedException((ChangesetClosedException) e);
440 return;
441 }
442
443 if (e instanceof MissingOAuthAccessTokenException) {
444 explainMissingOAuthAccessTokenException((MissingOAuthAccessTokenException) e);
445 return;
446 }
447
448 if (e instanceof OsmApiException) {
449 OsmApiException oae = (OsmApiException) e;
450 switch(oae.getResponseCode()) {
451 case HttpURLConnection.HTTP_PRECON_FAILED:
452 explainPreconditionFailed(oae);
453 return;
454 case HttpURLConnection.HTTP_GONE:
455 explainGoneForUnknownPrimitive(oae);
456 return;
457 case HttpURLConnection.HTTP_INTERNAL_ERROR:
458 explainInternalServerError(oae);
459 return;
460 case HttpURLConnection.HTTP_BAD_REQUEST:
461 explainBadRequest(oae);
462 return;
463 case HttpURLConnection.HTTP_NOT_FOUND:
464 explainNotFound(oae);
465 return;
466 case HttpURLConnection.HTTP_CONFLICT:
467 explainConflict(oae);
468 return;
469 case HttpURLConnection.HTTP_UNAUTHORIZED:
470 explainAuthenticationFailed(oae);
471 return;
472 case HttpURLConnection.HTTP_FORBIDDEN:
473 explainAuthorizationFailed(oae);
474 return;
475 case HttpURLConnection.HTTP_CLIENT_TIMEOUT:
476 explainClientTimeout(oae);
477 return;
478 case 509:
479 explainBandwidthLimitExceeded(oae);
480 return;
481 default:
482 explainGenericHttpException(oae);
483 return;
484 }
485 }
486 explainGeneric(e);
487 }
488
489 /**
490 * explains the case of an error due to a delete request on an already deleted
491 * {@link OsmPrimitive}, i.e. a HTTP response code 410, where we don't know which
492 * {@link OsmPrimitive} is causing the error.
493 *
494 * @param e the exception
495 */
496 public static void explainGoneForUnknownPrimitive(OsmApiException e) {
497 HelpAwareOptionPane.showOptionDialog(
498 Main.parent,
499 ExceptionUtil.explainGoneForUnknownPrimitive(e),
500 tr("Object deleted"),
501 JOptionPane.ERROR_MESSAGE,
502 ht("/ErrorMessages#GoneForUnknownPrimitive")
503 );
504 }
505
506 /**
507 * Explains an {@link Exception} to the user.
508 *
509 * @param e the {@link Exception}
510 */
511 public static void explainException(Exception e) {
512 if (ExceptionUtil.getNestedException(e, InvocationTargetException.class) != null) {
513 explainNestedInvocationTargetException(e);
514 return;
515 }
516 if (e instanceof OsmTransferException) {
517 explainOsmTransferException((OsmTransferException) e);
518 return;
519 }
520 explainGeneric(e);
521 }
522}
Note: See TracBrowser for help on using the repository browser.