@@ -48,10 +48,16 @@ protected static final class Error implements Serializable {
48
48
49
49
private final Integer code ;
50
50
private final String reason ;
51
+ private final boolean rejected ;
51
52
52
53
public Error (Integer code , String reason ) {
54
+ this (code , reason , false );
55
+ }
56
+
57
+ public Error (Integer code , String reason , boolean rejected ) {
53
58
this .code = code ;
54
59
this .reason = reason ;
60
+ this .rejected = rejected ;
55
61
}
56
62
57
63
/**
@@ -61,17 +67,26 @@ public Integer code() {
61
67
return code ;
62
68
}
63
69
70
+ /**
71
+ * Returns true if the error indicates that the API call was certainly not accepted by the
72
+ * server.
73
+ */
74
+ public boolean rejected () {
75
+ return rejected ;
76
+ }
77
+
64
78
/**
65
79
* Returns the reason that caused the exception.
66
80
*/
67
81
public String reason () {
68
82
return reason ;
69
83
}
70
84
71
- boolean isRetryable (Set <Error > retryableErrors ) {
85
+ boolean isRetryable (boolean idempotent , Set <Error > retryableErrors ) {
72
86
for (Error retryableError : retryableErrors ) {
73
- if ((retryableError .code () == null || retryableError .code ().equals (this .code ()))
74
- && (retryableError .reason () == null || retryableError .reason ().equals (this .reason ()))) {
87
+ boolean match = (retryableError .code () == null || retryableError .code ().equals (this .code ()))
88
+ && (retryableError .reason () == null || retryableError .reason ().equals (this .reason ()));
89
+ if (match && idempotent || match && retryableError .rejected ()) {
75
90
return true ;
76
91
}
77
92
}
@@ -111,7 +126,7 @@ public BaseServiceException(IOException exception, boolean idempotent) {
111
126
}
112
127
}
113
128
this .code = code ;
114
- this .retryable = idempotent && isRetryable (exception );
129
+ this .retryable = isRetryable (idempotent , exception );
115
130
this .reason = reason ;
116
131
this .idempotent = idempotent ;
117
132
this .location = location ;
@@ -123,7 +138,7 @@ public BaseServiceException(GoogleJsonError error, boolean idempotent) {
123
138
this .code = error .getCode ();
124
139
this .reason = reason (error );
125
140
this .idempotent = idempotent ;
126
- this .retryable = idempotent && isRetryable (error );
141
+ this .retryable = isRetryable (idempotent , error );
127
142
this .location = null ;
128
143
this .debugInfo = null ;
129
144
}
@@ -138,7 +153,7 @@ public BaseServiceException(int code, String message, String reason, boolean ide
138
153
this .code = code ;
139
154
this .reason = reason ;
140
155
this .idempotent = idempotent ;
141
- this .retryable = idempotent && new Error (code , reason ).isRetryable (retryableErrors ());
156
+ this .retryable = new Error (code , reason ).isRetryable (idempotent , retryableErrors ());
142
157
this .location = null ;
143
158
this .debugInfo = null ;
144
159
}
@@ -147,15 +162,15 @@ protected Set<Error> retryableErrors() {
147
162
return Collections .emptySet ();
148
163
}
149
164
150
- protected boolean isRetryable (GoogleJsonError error ) {
151
- return error != null && error (error ).isRetryable (retryableErrors ());
165
+ protected boolean isRetryable (boolean idempotent , GoogleJsonError error ) {
166
+ return error != null && error (error ).isRetryable (idempotent , retryableErrors ());
152
167
}
153
168
154
- protected boolean isRetryable (IOException exception ) {
169
+ protected boolean isRetryable (boolean idempotent , IOException exception ) {
155
170
if (exception instanceof GoogleJsonResponseException ) {
156
- return isRetryable ((( GoogleJsonResponseException ) exception ).getDetails ());
171
+ return isRetryable (idempotent , ((( GoogleJsonResponseException ) exception ).getDetails () ));
157
172
}
158
- return exception instanceof SocketTimeoutException ;
173
+ return idempotent && exception instanceof SocketTimeoutException ;
159
174
}
160
175
161
176
/**
@@ -187,8 +202,8 @@ public boolean idempotent() {
187
202
}
188
203
189
204
/**
190
- * Returns the service location where the error causing the exception occurred. Returns
191
- * {@code null} if not set.
205
+ * Returns the service location where the error causing the exception occurred. Returns {@code
206
+ * null} if not set.
192
207
*/
193
208
public String location () {
194
209
return location ;
@@ -224,7 +239,7 @@ public int hashCode() {
224
239
}
225
240
226
241
protected static String reason (GoogleJsonError error ) {
227
- if (error .getErrors () != null && !error .getErrors ().isEmpty ()) {
242
+ if (error .getErrors () != null && !error .getErrors ().isEmpty ()) {
228
243
return error .getErrors ().get (0 ).getReason ();
229
244
}
230
245
return null ;
0 commit comments