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

Last change on this file since 13849 was 13849, checked in by Don-vip, 6 years ago

SonarQube - fix minor code issues

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