Flutter how to handle Image.network error (like 404 or wrong url)

FlutterHttp Status-Code-404

Flutter Problem Overview


How to handle Image.network when the url is wrong or the destination leads to 404.

for example try

Image.network('https://image.tmdb.org/t/p/w92')

Flutter Solutions


Solution 1 - Flutter

I have handled the network image issue related to 404 by using an errorBuilder.

Image.network('Your image url...',
	errorBuilder: (BuildContext context, Object exception, StackTrace stackTrace) {
		return Text('Your error widget...');
	},
),

errorBuilder property

Solution 2 - Flutter

UPDATE: Look at the new accurate way which uses an inbuilt method, answered by @Niraj Phutane here which requires no plugins.


outdated old answer (before errorbuilder existed)

I recommend using cached_network_image which gives an option to add a placeholder image and also an error widget in case of a 404 or 403.

CachedNetworkImage(
   imageUrl: "http://via.placeholder.com/350x150",
   placeholder: (context, url) => new CircularProgressIndicator(),
   errorWidget: (context, url, error) => new Icon(Icons.error),
),

Solution 3 - Flutter

Instead of Network.image use NetworkImageWithRetry

https://pub.dartlang.org/documentation/flutter_image/latest/

Example:

var avatar = Image(
  image: NetworkImageWithRetry('http://example.com/avatars/123.jpg'),
);

Solution 4 - Flutter

You can display image from assets when you found 404 or any other error while loading image.

What I have done is:

  FadeInImage(
      image: NetworkImage("imageUrl"),
      placeholder: AssetImage(
          "assets/images/placeholder.jpg"),
      imageErrorBuilder:
          (context, error, stackTrace) {
        return Image.asset(
            'assets/images/error.jpg',
            fit: BoxFit.fitWidth);
      },
      fit: BoxFit.fitWidth,
    )

Check imageErrorBuilder property.

Solution 5 - Flutter

You can use ImageStream to handle errors.

class CustomProductImage extends StatefulWidget {
  final String image;

  const CustomProductImage(this.image);

  @override
  State<CustomProductImage> createState() => _CustomProductImageState();
}

class _CustomProductImageState extends State<CustomProductImage> {
  Widget mainWidget = const CircularProgressIndicator(); // Placeholder widget
  @override
  void initState() {
    super.initState();

    Image image = Image.network(widget.image, width: 50, height: 50);

    final ImageStream stream = image.image.resolve(ImageConfiguration.empty);

    stream.addListener(ImageStreamListener((info, call) {
      if (!completer) {
        completer = true;
        setState(() {
          mainWidget = image;
        });
      }
    }, onError: (dynamic exception, StackTrace? stackTrace) {
      print('Error is $exception , stack is $stackTrace');
      setState(() {
        mainWidget = const Icon(Icons.error); // Error Widget
      });
    }));
  }

  @override
  Widget build(BuildContext context) {
    return mainWidget;
  }
}

Solution 6 - Flutter

It's weird but you can't easily handle errors correctly with Image.Provider. Use this handy package: https://pub.dev/packages/flutter_advanced_networkimage

Then in you code:

backgroundImage: AdvancedNetworkImage(
                    "YOUR IMAGE URL", 
                    fallbackAssetImage: "YOUR DEAULT ASSERT IMAGE eg:assets/default.png"
                  )

Solution 7 - Flutter

I had the same problem, but, I solved it using the property 'imageErrorBuilder' of the FadeInImage class.

Here is a link about that: https://api.flutter.dev/flutter/widgets/Image/errorBuilder.html

The example was made for Image.network(), but it also work for FadeInImage.

Here's my code:

FadeInImage(
  imageErrorBuilder: (BuildContext context, Object exception, StackTrace stackTrace) {
    print('Error Handler'); 
    return Container(
      width: 100.0,
      height: 100.0,
      child: Image.asset('assets/img/no_disponible.jpg'),
    );
  },
  placeholder: AssetImage('assets/img/loading.gif'), 
  image: NetworkImage(product.getImg()),
  fit: BoxFit.cover,
  height: 100.0,
  width: 100.0,
), 

The function of imageErrorBuilder will be execute for example, if the direction of the page doesn't exist.

I'm using Flutter 1.20.1

Solution 8 - Flutter

Can use errorBuilder from Image.network or Image.asset

Image.network(
       path.image,
       width: 40,
       height: 40,
       errorBuilder: (BuildContext context, Object exception,
            StackTrace? stackTrace) {
         return const Text('šŸ˜¢');
       },

Solution 9 - Flutter

I used the basic Image widget and added an error builder for errors and a loadingBuilder for loading status and for the actual image I used NetworkImageWithRetry so that it will try to load the image many times and give you an error at the end if it couldn't load the image.

Image(
      image: NetworkImageWithRetry(
      'http://ImageUrl.png',),
      errorBuilder: (context, exception, stackTrack) => Icon(Icons.error,),
      loadingBuilder: (context, exception, stackTrack) => CircularProgressIndicator(),
    )

Solution 10 - Flutter

For those who are using firebase storage

The above methods didn't help me at all. When the object is not found in firebase, I got an exception "Null is not a type of List<int>". So I decided to verify if the Unit8List values are valid or not. If it's valid then we are ready to show the image otherwise use any widgets as placeholder.

Future<String?> getImgUrl()async{
//Storage structre: avatars/+919999999999/avatar.jpg
//Permanent url of an image without tokens
//%2F means "/"
//%2B mans "+"

String imgUrl = "https://firebasestorage.googleapis.com/v0/b/yourFIrebaseProjectID/o/avatars%2F%2B919999999999%2Favatar.jpg?alt=media";

    try {
      Uint8List bytes = (await NetworkAssetBundle(Uri.parse(imgUrl)).load(imgUrl)).buffer.asUint8List();
      print("The image exists!");
      return imgUrl;
    } catch (e) {
      print("Error: $e");
      return null;
    }
  }




 Widget futureBulder(){
    return FutureBuilder(
      future: getImgUrl(),
      builder: (BuildContext context, AsyncSnapshot<String?> snapshot) {
bool error = snapshot.data==null;
//I use NetworkImage for demonstration purpose, use it whatever widget u want
        return CircleAvatar(
         backgroundImage: error? null : NetworkImage(snapshot.data!),
        );
      },
    );
  }

Solution 11 - Flutter

I have implemented this StatefulWidget for the same case, hope this helps!!!

    class NetworkImageHandlerViewer extends StatefulWidget {
      final String imageURL;
      bool errorFoundInImageLoad = false;
      NetworkImageHandlerViewer({
        Key key,
        @required this.imageURL,
      }) : super(key: key);

      @override
      _NetworkImageHandlerViewerState createState() =>
          _NetworkImageHandlerViewerState();
    }

    class _NetworkImageHandlerViewerState extends State<NetworkImageHandlerViewer> {
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            Container(
              height: 200,
              // height: MediaQuery.of(context).size.height,
              width: MediaQuery.of(context).size.width,
              // color: Colors.black,
              child: (widget.errorFoundInImageLoad)
                  ? Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text(
                          "Unable To Fetch Image",
                        ),
                        IconButton(
                          iconSize: 40,
                          onPressed: () {
                            setState(() {
                              if (mounted) {
                                print("reloading image again");
                                setState(() {
                                  widget.errorFoundInImageLoad = false;
                                });
                              }
                            });
                          },
                          icon: Icon(Icons.refresh),
                        ),
                        Text(
                          "Tap Refresh Icon To Reload!!!",
                        ),
                      ],
                    )
                  : Image.network(
                      // widget.question.fileInfo[0].remoteURL,
                      widget.imageURL,
                      //
                      loadingBuilder: (context, child, loadingProgress) =>
                          (loadingProgress == null)
                              ? child
                              : Center(
                                  child: CircularProgressIndicator(),
                                ),
                      errorBuilder: (context, error, stackTrace) {
                        Future.delayed(
                          Duration(milliseconds: 0),
                          () {
                            if (mounted) {
                              setState(() {
                                widget.errorFoundInImageLoad = true;
                              });
                            }
                          },
                        );
                        return SizedBox.shrink();
                      },
                    ),
            ),
            SizedBox(height: 25),
          ],
        );
      }
    }

Solution 12 - Flutter

https://pub.dev/packages/extended_image

the plugin makes it easy to handle errors in Network image load

import 'package:flutter/material.dart';
import 'package:extended_image/extended_image.dart';

class ImageHolder extends StatefulWidget {
  const ImageHolder(
      {Key? key,
      required this.url,
      required this.imageHeight,
      required this.imageWidth})
      : super(key: key);

  final String url;
  final double imageHeight;
  final double imageWidth;

  @override
  _ImageHolderState createState() => _ImageHolderState();
}

class _ImageHolderState extends State<ImageHolder>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  @override
  void initState() {
    _controller = AnimationController(
        vsync: this,
        duration: const Duration(seconds: 3),
        lowerBound: 0.0,
        upperBound: 1.0);
    super.initState();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return ExtendedImage.network(
      widget.url,
      fit: BoxFit.contain,
      cache: true,
      loadStateChanged: (ExtendedImageState state) {
        switch (state.extendedImageLoadState) {
          case LoadState.loading:
            _controller.reset();
            return Image.asset(
              'assets/images/loading.gif',
              fit: BoxFit.fill,
            );
          case LoadState.completed:
            _controller.forward();
            return FadeTransition(
              opacity: _controller,
              child: ExtendedRawImage(
                image: state.extendedImageInfo?.image,
                width: widget.imageWidth,
                height: widget.imageHeight,
              ),
            );
          case LoadState.failed:
            _controller.reset();
            state.imageProvider.evict();
            return Image.asset(
              'assets/images/failed.jpg',
            );
        }
      },
    );
  }
}

Solution 13 - Flutter

CachedNetworkImage(
  placeholder: (context, url) =>
               Center(child: new CircularProgressIndicator()),
  errorWidget: (context, url, error) => 
               Icon(Icons.error),
  imageUrl: image,
  fit: BoxFit.fill,
              )

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionmohamed zayaniView Question on Stackoverflow
Solution 1 - FlutterNiraj PhutaneView Answer on Stackoverflow
Solution 2 - FlutterPhani RithvijView Answer on Stackoverflow
Solution 3 - Fluttermohamed zayaniView Answer on Stackoverflow
Solution 4 - FlutterPratik ButaniView Answer on Stackoverflow
Solution 5 - FlutterBIS TechView Answer on Stackoverflow
Solution 6 - FlutterHarold LomoteyView Answer on Stackoverflow
Solution 7 - FlutterMiguel Ángel Gómez PérezView Answer on Stackoverflow
Solution 8 - Flutterluis tundisiView Answer on Stackoverflow
Solution 9 - FlutterKhaled MahmoudView Answer on Stackoverflow
Solution 10 - FlutterRajesh Jr.View Answer on Stackoverflow
Solution 11 - FlutterMrudul AddipalliView Answer on Stackoverflow
Solution 12 - FlutterJaveed IshaqView Answer on Stackoverflow
Solution 13 - FlutterReshnu chandranView Answer on Stackoverflow