5

I have Generic class to request server with named ReusableRequestServer, this class will handle some exception if an error occurs while making a request to the server.

ReusableRequestServer

class ReusableRequestServer<T> {
  Future<T> requestServer(FutureOr<T> requestServer()) async {
    try {
      return await requestServer();
    } on FormatException catch (_) {
      throw ConstText.FORMAT_EXCEPTION;
    } on TimeoutException catch (_) {
      throw ConstText.TIMEOUT_EXCEPTION;
    } on SocketException catch (_) {
      throw ConstText.NO_CONNECTION;
    } catch (e) {
      throw e.toString();
    }
  }
}

final reusableRequestServer = ReusableRequestServer();

I have simple get request to get version mobile from server , i have also implemented ReusableRequestServer too.

Get Request

class MobileVersionApi {
  Future<List<MobileVersionModel>> getNewestMobileVersion() async {
    var result = await reusableRequestServer.requestServer(() async {
      final response = await http
          .get('${appConfig.baseApiUrl}/${appConfig.mobileVersionController}/getNewestVersion')
          .timeout(Duration(seconds: 10));
      final Map<String, dynamic> responseJson = json.decode(response.body);
      if (responseJson["status"] == "ok") {
        List mobileVersionList = responseJson["data"];
        List<MobileVersionModel> result =
            mobileVersionList.map((json) => MobileVersionModel.fromjson(json)).toList();
        return result;
      } else {
        throw responseJson['message'];
      }
    });
    return result;
  }
}

final mobileVersionApi = MobileVersionApi();

But the problem is when i consume the request in futurebuilder, even though I've handled it in 2 ways :

  • Create separated Future , to avoid directly passing future in futurebuilder
  • Handle with Try Catch

The Exception not catched in if snapshot.hasError and make the app crash.

FutureBuilder

Future<List<MobileVersionModel>> mobileVersion;
  Future<List<AppInfoModel>> appInfo;

  @override
  void initState() {
    super.initState();
    final appInfoProvider = Provider.of<AppInfoProvider>(context, listen: false);
    mobileVersion = getMobileVersion();
    appInfo = getAppInfo(appInfoProvider);
  }

  Future<List<MobileVersionModel>> getMobileVersion() async {
    try {
      final result = await mobileVersionApi.getNewestMobileVersion();
      return result;
    } catch (e) {
      globalF.showToast(message: e, isError: true);
      return null;
    }
  }

  Future<List<AppInfoModel>> getAppInfo(AppInfoProvider appInfoProvider) async {
    try {
      final result = appInfoApi.getLogoClient().then((value) {
        appInfoProvider.setAppInfo(value);
        if (value[0].updateTime != appInfoProvider.appInfo.updateTime) {
          globalF.clearCacheApp(); //clears all data in cache.
        }
      });
      return result;
    } catch (e) {
      globalF.showToast(message: e, isError: true);
      return null;
    }
  }

Widget build(BuildContext context) {
    return Scaffold(
      body: Consumer2<GlobalProvider, UserProvider>(
        builder: (_, globalProvider, userProvider, __) => FutureBuilder(
          future: Future.wait([
            mobileVersion,
            appInfo,
          ]),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return LoadingFutureBuilder();
            } else {
              if (snapshot.hasError) {
                return ErrorFutureBuilder(errorText: snapshot.error.toString());
              } else {
                  return Text('Hore');
              }
            }
          },
        ),
      ),
    );
  }

Error

Exception has occurred.
SocketException (SocketException: Failed host lookup: 'xxx.net' (OS Error: No address associated with hostname, errno = 7))

enter image description here I missed somewhere ? Thank's

2 Answers 2

19

at catch statement try return Future.error.

Ex:

catch (e){
   return Future.error(e.toString());
}
Sign up to request clarification or add additional context in comments.

1 Comment

saved my day day. +1
1
Future<List<MobileVersionModel>> getNewestMobileVersion() async {
try{
    var result = await reusableRequestServer.requestServer(() async {
      final response = await http
          .get('${appConfig.baseApiUrl}/${appConfig.mobileVersionController}/getNewestVersion')
          .timeout(Duration(seconds: 10));
      final Map<String, dynamic> responseJson = json.decode(response.body);
      if (responseJson["status"] == "ok") {
        List mobileVersionList = responseJson["data"];
        List<MobileVersionModel> result =
            mobileVersionList.map((json) => MobileVersionModel.fromjson(json)).toList();
        return result;
      } else {
        throw responseJson['message'];
      }
    });}
catch(e) {
//catch error here
}
    return result;
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.