diff --git a/packages/neon_framework/lib/src/models/account.dart b/packages/neon_framework/lib/src/models/account.dart index ecda2360135..67eacd6e246 100644 --- a/packages/neon_framework/lib/src/models/account.dart +++ b/packages/neon_framework/lib/src/models/account.dart @@ -78,6 +78,7 @@ abstract class Account implements Credentials, Findable, Built = T Function(Uint8List); /// range or if the request has timed out. const kMaxTries = 3; -/// The default timeout for requests. -/// -/// Requests that take longer than this duration will be canceled. -const kDefaultTimeout = Duration(seconds: 30); - /// A singleton class that handles requests to the Nextcloud API. /// /// Requests need to be made through the [nextcloud](https://pub.dev/packages/nextcloud) @@ -81,8 +77,6 @@ class RequestManager { required Converter converter, required UnwrapCallback unwrap, AsyncValueGetter>? getCacheHeaders, - bool disableTimeout = false, - Duration timeLimit = kDefaultTimeout, }) async { if (subject.isClosed) { return; @@ -125,10 +119,7 @@ class RequestManager { // Save the new cache parameters and return. if (parameters case CacheParameters(:final etag) when etag != null && getCacheHeaders != null) { try { - final newHeaders = await timeout( - getCacheHeaders.call, - timeLimit: timeLimit, - ); + final newHeaders = await getCacheHeaders.call(); if (subject.isClosed) { return; } @@ -146,7 +137,7 @@ class RequestManager { subject.add(Result(unwrapped, null, isLoading: false, isCached: true)); return; } - } on TimeoutException catch (error) { + } on HttpTimeoutException catch (error) { _log.info( 'Fetching cache parameters timed out. Assuming expired.', error, @@ -171,24 +162,19 @@ class RequestManager { subject.add(subject.value.asLoading()); } + var client = httpClient; + // Assume the request is for WebDAV if the Content-Type is application/xml, + if (request.headers['content-type']?.split(';').first == 'application/xml') { + client ??= account.client.webdav.csrfClient; + } else { + client ??= account.client; + } + for (var i = 0; i < kMaxTries; i++) { try { - final response = await timeout( - () async { - var client = httpClient; - // Assume the request is for WebDAV if the Content-Type is application/xml, - if (request.headers['content-type']?.split(';').first == 'application/xml') { - client ??= account.client.webdav.csrfClient; - } else { - client ??= account.client; - } - - final streamedResponse = await client.send(request); - return http.Response.fromStream(streamedResponse); - }, - disableTimeout: disableTimeout, - timeLimit: timeLimit, - ); + final streamedResponse = await client.send(request); + final response = await http.Response.fromStream(streamedResponse); + if (subject.isClosed) { return; } @@ -200,12 +186,8 @@ class RequestManager { response, ); break; - } on TimeoutException catch (error, stackTrace) { - _log.info( - 'Request timeout', - error, - stackTrace, - ); + } on HttpTimeoutException catch (error) { + _log.info('Request timeout', error); if (subject.isClosed) { return; diff --git a/packages/neon_framework/test/request_manager_test.dart b/packages/neon_framework/test/request_manager_test.dart index 705b7805368..10a218de014 100644 --- a/packages/neon_framework/test/request_manager_test.dart +++ b/packages/neon_framework/test/request_manager_test.dart @@ -161,76 +161,6 @@ void main() { await subject.close(); }); - test('timeout request', () async { - var subject = BehaviorSubject>(); - - expect( - subject.stream, - emitsInOrder([ - equals(Result.loading()), - equals(Result.error('TimeoutException after 0:00:00.050000: Future not completed')), - emitsDone, - ]), - ); - - expect( - subject.stream, - neverEmits([ - equals(Result.success(base64String('Test value'))), - emitsDone, - ]), - ); - - await RequestManager.instance.wrap( - account: account, - subject: subject, - getRequest: () => http.Request('GET', Uri(host: 'delay')), - converter: const BinaryResponseConverter(), - unwrap: (deserialized) => base64.encode(deserialized), - timeLimit: const Duration(milliseconds: 50), - ); - - await subject.close(); - - subject = BehaviorSubject>.seeded(Result.success('Seed value')); - - expect( - subject.stream, - emitsInOrder([ - equals(Result.success('Seed value')), - equals(Result.success('Seed value').asLoading()), - equals( - Result( - 'Seed value', - 'TimeoutException after 0:00:00.050000: Future not completed', - isLoading: false, - isCached: false, - ), - ), - emitsDone, - ]), - ); - - expect( - subject.stream, - neverEmits([ - equals(Result.success(base64String('Test value'))), - emitsDone, - ]), - ); - - await RequestManager.instance.wrap( - account: account, - subject: subject, - getRequest: () => http.Request('GET', Uri(host: 'delay')), - converter: const BinaryResponseConverter(), - unwrap: (deserialized) => base64.encode(deserialized), - timeLimit: const Duration(milliseconds: 50), - ); - - await subject.close(); - }); - test('throwing request', () async { var subject = BehaviorSubject>(); @@ -385,88 +315,6 @@ void main() { ).called(1); }); - test('timeout request', () async { - var subject = BehaviorSubject>(); - - expect( - subject.stream, - emitsInOrder([ - equals(Result.loading()), - equals(Result(base64String('Cached value'), null, isLoading: true, isCached: true)), - equals( - Result( - base64String('Cached value'), - 'TimeoutException after 0:00:00.050000: Future not completed', - isLoading: false, - isCached: true, - ), - ), - emitsDone, - ]), - ); - - expect( - subject.stream, - neverEmits([ - equals(Result.success(base64String('Test value'))), - emitsDone, - ]), - ); - - await RequestManager.instance.wrap( - account: account, - subject: subject, - getRequest: () => http.Request('GET', Uri(host: 'delay')), - converter: const BinaryResponseConverter(), - unwrap: (deserialized) => base64.encode(deserialized), - timeLimit: const Duration(milliseconds: 50), - ); - - await subject.close(); - verify(() => cache.get(account, any())).called(1); - verifyNever(() => cache.set(any(), any(), any())); - - subject = BehaviorSubject>.seeded(Result.success('Seed value')); - - expect( - subject.stream, - emitsInOrder([ - equals(Result.success('Seed value')), - equals(Result(base64String('Cached value'), null, isLoading: true, isCached: true)), - equals( - Result( - base64String('Cached value'), - 'TimeoutException after 0:00:00.050000: Future not completed', - isLoading: false, - isCached: true, - ), - ), - emitsDone, - ]), - ); - - expect( - subject.stream, - neverEmits([ - equals(Result.success(base64String('Test value'))), - emitsDone, - ]), - ); - - await RequestManager.instance.wrap( - account: account, - subject: subject, - getRequest: () => http.Request('GET', Uri(host: 'delay')), - converter: const BinaryResponseConverter(), - unwrap: (deserialized) => base64.encode(deserialized), - timeLimit: const Duration(milliseconds: 50), - ); - - await subject.close(); - verify(() => cache.get(account, any())).called(1); - verifyNever(() => cache.set(any(), any(), any())); - }); - test('throwing request', () async { var subject = BehaviorSubject>();