Skip to content

Commit 667281e

Browse files
authored
Fix retry logic (#1762)
Closes #1556
1 parent 35730f7 commit 667281e

File tree

1 file changed

+41
-35
lines changed

1 file changed

+41
-35
lines changed

lib/src/http.dart

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -92,39 +92,7 @@ class _PubHttpClient extends http.BaseClient {
9292

9393
_logResponse(streamedResponse);
9494

95-
var status = streamedResponse.statusCode;
96-
// 401 responses should be handled by the OAuth2 client. It's very
97-
// unlikely that they'll be returned by non-OAuth2 requests. We also want
98-
// to pass along 400 responses from the token endpoint.
99-
var tokenRequest = streamedResponse.request.url == oauth2.tokenEndpoint;
100-
if (status < 400 || status == 401 || (status == 400 && tokenRequest)) {
101-
return streamedResponse;
102-
}
103-
104-
if (status == 406 &&
105-
request.headers['Accept'] == PUB_API_HEADERS['Accept']) {
106-
fail("Pub ${sdk.version} is incompatible with the current version of "
107-
"${request.url.host}.\n"
108-
"Upgrade pub to the latest version and try again.");
109-
}
110-
111-
if (status == 500 &&
112-
(request.url.host == "pub.dartlang.org" ||
113-
request.url.host == "storage.googleapis.com")) {
114-
var message = "HTTP error 500: Internal Server Error at "
115-
"${request.url}.";
116-
117-
if (request.url.host == "pub.dartlang.org" ||
118-
request.url.host == "storage.googleapis.com") {
119-
message += "\nThis is likely a transient error. Please try again "
120-
"later.";
121-
}
122-
123-
fail(message);
124-
}
125-
126-
throw new PubHttpException(
127-
await http.Response.fromStream(streamedResponse));
95+
return streamedResponse;
12896
}
12997

13098
/// Whether extra metadata headers should be added to [request].
@@ -216,10 +184,48 @@ final _pubClient = new _PubHttpClient();
216184
/// we're waiting for them to come back up.
217185
final _retriedHosts = new Set<String>();
218186

187+
/// Intercepts all requests and throws exceptions if the response was not
188+
/// considered successful.
189+
class _ThrowingClient extends http.BaseClient {
190+
final http.Client _inner;
191+
192+
_ThrowingClient(this._inner);
193+
194+
Future<http.StreamedResponse> send(http.BaseRequest request) async {
195+
final streamedResponse = await _inner.send(request);
196+
197+
var status = streamedResponse.statusCode;
198+
// 401 responses should be handled by the OAuth2 client. It's very
199+
// unlikely that they'll be returned by non-OAuth2 requests. We also want
200+
// to pass along 400 responses from the token endpoint.
201+
var tokenRequest = streamedResponse.request.url == oauth2.tokenEndpoint;
202+
if (status < 400 || status == 401 || (status == 400 && tokenRequest)) {
203+
return streamedResponse;
204+
}
205+
206+
if (status == 406 &&
207+
request.headers['Accept'] == PUB_API_HEADERS['Accept']) {
208+
fail("Pub ${sdk.version} is incompatible with the current version of "
209+
"${request.url.host}.\n"
210+
"Upgrade pub to the latest version and try again.");
211+
}
212+
213+
if (status == 500 &&
214+
(request.url.host == "pub.dartlang.org" ||
215+
request.url.host == "storage.googleapis.com")) {
216+
fail("HTTP error 500: Internal Server Error at ${request.url}.\n"
217+
"This is likely a transient error. Please try again later.");
218+
}
219+
220+
throw new PubHttpException(
221+
await http.Response.fromStream(streamedResponse));
222+
}
223+
}
224+
219225
/// The HTTP client to use for all HTTP requests.
220226
final httpClient = new ThrottleClient(
221227
16,
222-
new RetryClient(_pubClient,
228+
new _ThrowingClient(new RetryClient(_pubClient,
223229
retries: 5,
224230
when: (response) => const [502, 503, 504].contains(response.statusCode),
225231
delay: (retryCount) {
@@ -245,7 +251,7 @@ final httpClient = new ThrottleClient(
245251
log.message(
246252
"It looks like ${request.url.host} is having some trouble.\n"
247253
"Pub will wait for a while before trying to connect again.");
248-
}));
254+
})));
249255

250256
/// The underlying HTTP client wrapped by [httpClient].
251257
http.Client get innerHttpClient => _pubClient._inner;

0 commit comments

Comments
 (0)