Avoid retrying queries after closing client (#4095)
diff --git a/lib/src/http.dart b/lib/src/http.dart
index d05c512..e9a94b4 100644
--- a/lib/src/http.dart
+++ b/lib/src/http.dart
@@ -40,15 +40,31 @@
http.Client _inner;
+ /// We manually keep track of whether the client was closed,
+ /// indicating that no more networking should be done. (And thus we don't need
+ /// to retry failed requests).
+ bool _wasClosed = false;
+
_PubHttpClient([http.Client? inner]) : _inner = inner ?? http.Client();
@override
Future<http.StreamedResponse> send(http.BaseRequest request) async {
+ if (_wasClosed) {
+ throw StateError('Attempting to send request on closed client');
+ }
_requestStopwatches[request] = Stopwatch()..start();
request.headers[HttpHeaders.userAgentHeader] = 'Dart pub ${sdk.version}';
_logRequest(request);
-
- final streamedResponse = await _inner.send(request);
+ final http.StreamedResponse streamedResponse;
+ try {
+ streamedResponse = await _inner.send(request);
+ } on http.ClientException {
+ if (_wasClosed) {
+ // Avoid retrying in this case.
+ throw _ClientClosedException();
+ }
+ rethrow;
+ }
_logResponse(streamedResponse);
@@ -118,7 +134,10 @@
}
@override
- void close() => _inner.close();
+ void close() {
+ _wasClosed = true;
+ _inner.close();
+ }
}
/// The [_PubHttpClient] wrapped by [globalHttpClient].
@@ -417,3 +436,11 @@
return streamedResponse;
}
}
+
+/// Thrown by [_PubHttpClient.send] if the client was closed while the request
+/// was being processed. Notably it doesn't implement [http.ClientException],
+/// and thus does not trigger a retry by [retryForHttp].
+class _ClientClosedException implements Exception {
+ @override
+ String toString() => 'Request was made after http client was closed';
+}