Can a Future internally retry an http request if it fails in Flutter? Can a Future internally retry an http request if it fails in Flutter? flutter flutter

Can a Future internally retry an http request if it fails in Flutter?


The following extension method will take a factory for futures, create them and try them until the retry limit is reached:

extension Retry<T> on Future<T> Function() {  Future<T> withRetries(int count) async {    while(true) {      try {        final future = this();        return await future;      }       catch (e) {        if(count > 0) {          count--;        }        else {          rethrow;        }      }    }  }}

Assuming you have a rather plain dart method:

 Future<AppData> getJSONfromTheSite(String call) async {      final response = await http.get(Uri.parse('http://www.thesite.com/'));      if (response.statusCode == 200) {        return AppData.fromRawJson(response.body);      } else {        throw Exception('Error');      }  }

You can now call it like this:

try {  final result = (() => getJSONfromTheSite('call data')).withRetries(3);  // succeeded at some point, "result" being the successful result}catch (e) {  // failed 3 times, the last error is in "e"}

If you don't have a plain method that either succeeds or throws an exception, you will have to adjust the retry method to know when something is an error. Maybe use one of the more functional packages that have an Either type so you can figure out whether a return value is an error.


Inside catch() you can count how many times have you retried, if counter is less than three you return the same getJSONfromTheSite() function, but with the summed counter. And if the connection keeps failing on try{} and the counter is greater than three it will then returns the error.

Future<Result> getJSONfromTheSite(String call, {counter = 0}) async {            debugPrint('Network Attempt by getJSONfromTheSite');            try {              String? body = await tryGet();              if (body != null) {                return Result<AppData>.success(AppData.fromRawJson(response.body));              } else {                //return Result.error("Error","Status code not 200", 1);                return Result.error(title:"Error",msg:"Status code not 200", errorcode:1);              }            } catch (error) {                if(counter < 3) {                    counter += 1;                  return getJSONfromTheSite(call, counter: counter);                } else {                  return Result.error(title:"No connection",msg:"Status code not 200", errorcode:0);                }            }          }