How to catch "Unable to load asset: assets/images/sample_img_url.png"

Viewed 2444

Is there any way to catch the "Unable to load asset: assets/images/sample_img_url.png" error in Flutter?

What I am trying to do is load an asset image by providing its path(from API). But if I do not have an image that associates with the given path, I need to load a sample image.

I've created a custom placeholder widget as follows. But's it's not working as I expected. anyone can help me with this?

class ImagePlaceHolder extends StatelessWidget {
  final String path;
  final double width;

  const ImagePlaceHolder({Key key, this.path, this.width}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    Image finalImage;
    try{
      finalImage = Image.asset(
          path,
          width: width,
      );
    }
    catch(Exception){
      finalImage = Image.asset(
          "assets/images/app_update_logo.png",
          width: width,
      );
    }
    return finalImage;
  }
}
5 Answers

Okay, finally I found a really nice way to overcome this issue. Just use an error builder.

Image.asset(
     "assets/images/subjects/api_given_image_name.png",
     width: 90,
     errorBuilder: (BuildContext context, Object exception, StackTrace stackTrace) {
           return Image.asset(
                "assets/images/your_sample_image.png",
                width: 90,
           );
     },
)

You have to define the asset path in pubspec.yaml like the followings :

flutter:
  assets:
    - assets/my_icon.png
    - assets/background.png

To include all assets under a directory, specify the directory name with the / character at the end:

flutter:
  assets:
    - directory/
    - directory/subdirectory/

Official doc : https://flutter.dev/docs/development/ui/assets-and-images

I think the error should not be resolved in the runtime. So specify only existing image paths. In case you have no image in specified path you should not use it.

BUT. If you still want to catch the exception firstly you should understand that Image.asset works asynchronously. Exception throws later, that's why you can't catch it. Take a look at this GitHub issue, hope it helps.

You don't need to catch that exception to achieve what you want. You can use errorBuilder function to return any widget of you liking.

      Image.asset(
        "assets/images/app_update_logo.png",
        width: width,
        errorBuilder: (context, error, stackTrace) {
          return Image.asset(
            "assets/images/error_logo.png",
            width: width,
          );
        },
      );

Best of luck!

Just a quick updated answer for null safety:

Image.asset(
 "assets/images/subjects/api_given_image_name.png",
 width: 90,
 errorBuilder: (BuildContext context, Object exception, StackTrace? stackTrace) {
       return Image.asset(
            "assets/images/your_sample_image.png",
            width: 90,
       );
 },
)

needs the ? after StackTrace or will cryptically error.

Related