Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Does the package have Request Timeout? #121

Open
tyrone-horizonlabs opened this issue Sep 29, 2022 Discussed in #120 · 1 comment
Open

Does the package have Request Timeout? #121

tyrone-horizonlabs opened this issue Sep 29, 2022 Discussed in #120 · 1 comment

Comments

@tyrone-horizonlabs
Copy link

Discussed in #120

Originally posted by tyrone-horizonlabs September 29, 2022
I'm having an issue where when requesting an endpoint doesn't fail or throw an exception when the device has no internet connection.

Steps to reproduce:

  1. Make sure internet is available
  2. start a request to Hasura server (query or mutation).
  3. immediately turn off internet connection before the package finished the request.

From what I noticed, the request keeps retrying until I turn back the internet connection to ON but I need the package to throw the exception.

Does the package support a request timeout?

@OrlandoEduardo101
Copy link
Contributor

To resolve that, I create a custom client with timeout and inject to hasura

<script src="https://gist.github.com/OrlandoEduardo101/ecdbe73f7d4e8c8470ffc3db24f0ec74.js"></script>

// ignore_for_file: non_constant_identifier_names

import 'dart:async';
import 'package:http/http.dart' as http;

// as dart does not support tuples i create an Either class
class _Either<L, R> {
  final L? left;
  final R? right;

  _Either(this.left, this.right);
  _Either.Left(L this.left) : right = null;
  _Either.Right(R this.right) : left = null;
}

class TimeoutClient extends http.BaseClient {
  final http.Client _httpClient;
  final Duration timeout;

  TimeoutClient(
      {http.Client? httpClient, this.timeout = const Duration(seconds: 30)})
      : _httpClient = httpClient ?? http.Client();

  Future<http.StreamedResponse> send(http.BaseRequest request) async {
    // wait for result between two Futures (the one that is reached first) in silent mode (no throw exception)
    _Either<http.StreamedResponse, Exception> result = await Future.any([
      Future.delayed(
          timeout,
          () => _Either.Right(
                TimeoutException(
                    'Client connection timeout after ${timeout.inMilliseconds} ms.'),
              )),
      Future(() async {
        try {
          return _Either.Left(await _httpClient.send(request));
        } on Exception catch (e) {
          return _Either.Right(e);
        }
      })
    ]);

    // this code is reached only for first Future response,
    // the second Future is ignorated and does not reach this point
    if (result.right != null) {
      throw result.right!;
    }

    return result.left!;
  }
}
class CustomHasuraConnect {
  final String url;

  CustomHasuraConnect(this.url);
  HasuraConnect getConnect(FirebaseAuth auth, StorageController controller, AuthStore authStore, CustomFlutterConnectivity connectivity) {
    return HasuraConnect(
      url,
      // reconnectionAttemp: 5,
      httpClientFactory: () => TimeoutClient(),
      interceptors: [
        // CacheInterceptor(controller),
        // TimeoutInterceptor(),
        TokenInterceptor(auth, connectivity, authStore),
        LogInterceptor(),
        //HiveCacheInterceptor(),
      ],

      headers: {},
    );
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants