As Application becomes bigger, you will face problems of network error handling. Network Error handling can be tricky — in some cases, you should simply show a message, while some errors require to perform navigation to a screen.

In this tutorial, we will use dio HTTP client for HTTP request and HTTP error handling. We also use FutureBuilder to progress indicator when fetching data from the network.

Flutter dio and FutureBuilder


Dio is an http connection library. When you need to do something more advanced like Interceptors, HTTP error handling, Global configuration, FormData, Request Cancellation. This can be done by using Dio.Here we use SWAPI API.

Add dependency

 You need to go to file pubspec.yamlinside Flutter project and add this line.Check for the latest version.

  dio: 2.1.x  

Performing a GET request:

_fetchData() async {
    Dio dio = new Dio();
    dio.options.baseUrl = url;
    dio.options.connectTimeout = 5000;
    dio.options.receiveTimeout = 30000;
    Response response = await dio.get(url);

    return response;

Here, we have create instance of Dio with an http options.The Options class describes the http request information and configuration. Each Dio instance has a base config for all requests maked by itself, and we can override the base config with [Options] when make a single request.


It serves as a bridge between the Future and the widget’s UI. It is a widget that returns another widget based on the Future’s execution result.

FutureBuilder lets you easily determine the current state of a future and choose what to show while the data’s loading and when it’s available.

              future: this._fetchData(),
              builder: (context, snapshot) {
                switch (snapshot.connectionState) {
                  case ConnectionState.none:
                  case ConnectionState.waiting:
                    return Center(
                      child: CircularProgressIndicator(),
                  case ConnectionState.done:
                    if (snapshot.hasError) {
                      DioError error = snapshot.error;
                      String message = error.message;
                      if (error.type == DioErrorType.CONNECT_TIMEOUT)
                        message = 'Connection Timeout';
                      else if (error.type == DioErrorType.RECEIVE_TIMEOUT)
                        message = 'Receive Timeout';
                      else if (error.type == DioErrorType.RESPONSE)
                        message =
                            '404 server not found ${error.response.statusCode}';
                      return Text('Error: ${message}');
                    List<String> people = new List<String>();
                    Response response =;
                    for (int i = 0; i <['results'].length; i++) {
                    return Expanded(
                        child: ListView.builder(
                      itemCount: people.length,
                      itemBuilder: (BuildContext context, int index) {
                        return ListTile(
                          title: Text(people[index]),

Start by giving FutureBuilder a future, and then a builder. Make sure to check the state of the future with connectionState and display an appropriate widget when your future is busy. Finally, it’s good practice to check that no error has occurred while your future was resolving.

Download this project from GitHub