|
33 | 33 | */
|
34 | 34 | @InternalApi
|
35 | 35 | public final class StorageException extends BaseHttpServiceException {
|
| 36 | +private static final String INTERNAL_ERROR = "internalError"; |
| 37 | +private static final String CONNECTION_CLOSED_PREMATURELY = "connectionClosedPrematurely"; |
| 38 | +private static final String CONNECTION_RESET = "connectionReset"; |
36 | 39 |
|
37 | 40 | // see: https://cloud.google.com/storage/docs/resumable-uploads-xml#practices
|
38 | 41 | private static final Set<Error> RETRYABLE_ERRORS =
|
@@ -43,7 +46,9 @@ public final class StorageException extends BaseHttpServiceException {
|
43 | 46 | new Error(500, null),
|
44 | 47 | new Error(429, null),
|
45 | 48 | new Error(408, null),
|
46 |
| -new Error(null, "internalError")); |
| 49 | +new Error(null, INTERNAL_ERROR), |
| 50 | +new Error(null, CONNECTION_CLOSED_PREMATURELY), |
| 51 | +new Error(null, CONNECTION_RESET)); |
47 | 52 |
|
48 | 53 | private static final long serialVersionUID = -4168430271327813063L;
|
49 | 54 |
|
@@ -55,6 +60,10 @@ public StorageException(int code, String message, Throwable cause) {
|
55 | 60 | super(code, message, null, true, RETRYABLE_ERRORS, cause);
|
56 | 61 | }
|
57 | 62 |
|
| 63 | +public StorageException(int code, String message, String reason, Throwable cause) { |
| 64 | +super(code, message, reason, true, RETRYABLE_ERRORS, cause); |
| 65 | +} |
| 66 | + |
58 | 67 | public StorageException(IOException exception) {
|
59 | 68 | super(exception, true, RETRYABLE_ERRORS);
|
60 | 69 | }
|
@@ -73,4 +82,23 @@ public static StorageException translateAndThrow(RetryHelperException ex) {
|
73 | 82 | BaseServiceException.translate(ex);
|
74 | 83 | throw new StorageException(UNKNOWN_CODE, ex.getMessage(), ex.getCause());
|
75 | 84 | }
|
| 85 | + |
| 86 | +/** |
| 87 | +* Translate IOException to a StorageException representing the cause of the error. This method |
| 88 | +* defaults to idempotent always being {@code true}. Additionally, this method translates |
| 89 | +* transient issues Connection Closed Prematurely and Connection Reset as retryable errors. |
| 90 | +* |
| 91 | +* @returns {@code StorageException} |
| 92 | +*/ |
| 93 | +public static StorageException translate(IOException exception) { |
| 94 | +if (exception.getMessage().contains("Connection closed prematurely")) { |
| 95 | +return new StorageException( |
| 96 | +0, exception.getMessage(), CONNECTION_CLOSED_PREMATURELY, exception); |
| 97 | +} else if (exception.getMessage().contains("Connection reset")) { |
| 98 | +return new StorageException(0, exception.getMessage(), CONNECTION_RESET, exception); |
| 99 | +} else { |
| 100 | +// default |
| 101 | +return new StorageException(exception); |
| 102 | +} |
| 103 | +} |
76 | 104 | }
|
0 commit comments