8

This is probably a noob question, but how do I make my response throw an exception if the user does not have an internet connection or if it takes too long to fetch the data?

Future<TransactionModel> getDetailedTransaction(String crypto) async {
//TODO Make it return an error if there is no internet or takes too long!

 http.Response response = await http.get(crypto);

  return parsedJson(response);

   }
TB_98
  • 99
  • 1
  • 1
  • 5
  • Check the answer for this question : https://stackoverflow.com/questions/49648022/check-whether-there-is-an-internet-connection-available-on-flutter-app – Pol Apr 05 '20 at 05:31

4 Answers4

24

You should surround it with try catch block, like so:

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

int timeout = 5;
try {
  http.Response response = await http.get('someUrl').
      timeout(Duration(seconds: timeout));
  if (response.statusCode == 200) {
    // do something
  } else {
    // handle it
  }
} on TimeoutException catch (e) {
  print('Timeout Error: $e');
} on SocketException catch (e) {
  print('Socket Error: $e');
} on Error catch (e) {
  print('General Error: $e');
}

Socket exception will be raised immediately if the phone is aware that there is no connectivity (like both WiFi and Data connection are turned off).

Timeout exception will be raised after the given timeout, like if the server takes too long to reply or users connection is very poor etc.

Also don't forget to handle the situation if the response code isn't = 200.

Uroš
  • 1,428
  • 1
  • 12
  • 18
  • Sorry for the long wait. Thanks a lot it works perfectly! – TB_98 Apr 11 '20 at 04:50
  • @Uros but phone connected to wifi still getting socket exception error. – s.j Apr 08 '21 at 06:55
  • Having no internet connection is only one of the reasons why the```SocketException``` thrown. I mean there are some other problems that my cause the ```SocketException``` to be thrown. Is there any way to precisely identify if the cause is having no internet connection? – Ehsan Askari Oct 05 '21 at 11:04
  • Also to add, TimeoutException requires import 'dart:async'; and SocketException requires import 'dart:io'; – A5H1Q Oct 16 '22 at 07:08
2

You don't need to use http to check the connectivity yourself, simply use connectivity library

Jim
  • 6,928
  • 1
  • 7
  • 18
  • Thanks for the input! I'm using the BLoC design pattern for this project, so this solution did not end up being compatible w/ my project. – TB_98 Apr 11 '20 at 04:53
  • 2
    The original poster asked how to check for internet connection, but the connectivity library package page in https://pub.dev/packages/connectivity expressely states that "on Android, this does not guarantee connection to Internet. For instance, the app might have wifi access but it might be a VPN or a hotel WiFi with no access.". Therefore this answer doesn't solve the poster question. – Fabio Pagano Feb 26 '21 at 12:29
1

You can use this plugin https://pub.dev/packages/data_connection_checker

So you can check prior if you have the connection, if not give a alert to the user that no internet connection. And if you have the internet connection then just proceed to your fetching part.

I will just link some resources below where it has been explained perfectly:

https://www.youtube.com/watch?v=u_Xyqo6lhFE

This is all things will be done prior to making an http call, but what if while making an http call the internet goes off then you can use the try catch block which @uros has mentioned.

Let me know if it works.

Sagar Acharya
  • 3,397
  • 4
  • 12
  • 34
  • That solution is good if you want to check data connection throughout your app, but I just wanted connection to be checked within that one fetch method. Thanks for the help! – TB_98 Apr 11 '20 at 04:48
0

This is my approach to check internet connection to check internet connection throughout full app

i create a common class called "connectivity" & use it everywhere in app to check connectivity.i use connectivity package by flutter.

My connectivity class

 Future<bool> check() async {
  var connectivityResult = await (Connectivity().checkConnectivity());
  if (connectivityResult == ConnectivityResult.mobile) {
    return true;
  } else if (connectivityResult == ConnectivityResult.wifi) {
    return true;
  }
  return false;
}

then i use this class like this:

 @override
  void initState() {
    super.initState();

    checkInternetConnection().then((internet) {
      if (internet != null && internet) {
        // Internet Present Case
        // do your task;
      } else {
        // No-Internet Case
        showAlertDialog(context);
      }
    });
  }