how to handle 404 exception with CachedNetworkImage in flutter
Asked Answered
D

6

31

When my image is not present in the server or if the image URL is not correct, I'm getting an exception error. How can I handle this error in flutter? Can I use future to handle this error? I tried the future but I couldn't figure it out.

Here is a screenshot:

enter image description here

Code

import 'package:cached_network_image/cached_network_image.dart';   
import './responsive/resp_safe_area.dart';
import './common/styling.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import './responsive/size_config.dart';


void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitUp,
  ]);
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final appTitle = "Bigshopy";

  @override
  Widget build(BuildContext context) {
    try {
      return MediaQuery(
        data: MediaQueryData(),
        child: ResponsiveSafeArea(builder: (context, size) {
          SafeSizeConfig().init(size);
          return MaterialApp(
            debugShowCheckedModeBanner: false,
            title: appTitle,
            theme: BigAppTheme.defaltTheme,
            home: Scaffold(
              appBar: AppBar(),
              body: SingleChildScrollView(
                child: Center(
                  child: Container(
                    child: CachedNetworkImage(
                      fit: BoxFit.fill,
                      imageUrl:
                          'http://192.168.1.3/bigshopy/assets/topItemCategory/login_main_img.png',
                      placeholder: (context, url) =>
                          CircularProgressIndicator(),
                      errorWidget: (context, url, error) =>
                          new Icon(Icons.error),
                    ),
                  ),
                ),
              ),
            ),
          );
        }),
      );
    } catch (error) {
      print(error);
    }
  }
}

Error Message

Exception has occurred. HttpExceptionWithStatus (HttpException: Invalid statusCode: 404, uri = http://192.168.1.3/assets/topItemCategory/login_main_img.png)

Dotterel answered 20/6, 2020 at 20:21 Comment(5)
Hey, man. Did you fix this problem? What's the solution?Euroclydon
Did you fix this problem?Omnifarious
I tried to solve this with a FutureBuilder but the canLaunchUrlString but this function returns true even though. Can someone please explain to me why the function canLaunchUrlString returns true even when the URL will return a 404 status?Dzoba
@HyungTaeCarapetoFigur As far as I know, this method only checks if the device contains an application capable of opening the URL scheme passed as an argument. It doesn't make the request, so it doesn't know if the response will be successfulViolette
@VictorEmanuel Oh good to know. I thought that function was there to avoid making try-catch blocks. Thanks, now I know I always have to put my code in try-catches when opening URLs.Dzoba
O
17

The IDE is telling you that there is an exception, but actually it's ok. The reason is apparently because the Dart VM doesn't recognize it as a caught exception even though it is. Just press the continue button or uncheck the breakpoint for uncaught exceptions. You'll see that your errorWidget will show up.

enter image description here

The author of the plugin actually added a FAQ about this issue.

Orthopedic answered 18/1, 2021 at 9:13 Comment(3)
This is fine until you have a list of images returned 404 and debugging that page requires you to click continue 50 times every time you perform a hot-reload. Is there a proper way to suppress this error at all?Bostwick
It worked! But does this ignore any exceptions that should be detected too?Vadavaden
@yukiyuki, This just means that it won't pause on the exceptions. You should still be able to see them if you check the logs in the debug console. And I think if the exceptions are serious enough the app will still crash.Orthopedic
H
2

I was getting the yellow letters on red background because I was logging the error via debugPrint!

CachedNetworkImage error httpStatus 404 is not String

When I removed the debugPrint I got my error text displayed (code is below).

CachedNetworkImage error httpStatus 404 is not String - solved
CachedNetworkImage(
  imageUrl: url,
  placeholder: (context, url) {
    return Center(
      child: CircularProgressIndicator(
        color: theme.contrastColor.shade500,
        strokeWidth: 2,
      ),
    );
  },
  errorWidget: (context, url, error) {
    // This was the reason for exception being triggered and rendered!
    debugPrint(error); // TODO: Remove this line!
    return Center(
      child: Text(
        'Error',
        style: TextStyle(color: Colors.red),
      ),
    );
  },
);
Holy answered 20/7, 2022 at 12:48 Comment(0)
I
1

We can override the behaviour of how Flutter handles an Error, https://docs.flutter.dev/testing/errors#:~:text=All%20errors%20caught,in%20the%20message.

void main() async {
  FlutterError.onError = (FlutterErrorDetails details) {
    if (details.library == 'image resource service' &&
        details.exception.toString().contains('404')) {
      print('Suppressed cachedNetworkImage Exception');
      return;
    }
    FlutterError.presentError(details);
  };
  runApp(const MyApp());
}
Idiomatic answered 27/10, 2023 at 10:38 Comment(0)
S
0

As Suragch stated, it's not really an error.

If you need to skip the exceptions during tests you can override FlutterError.onError the following way (do it at the first line of your test, not on setUp step):

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

final onError = FlutterError.onError;
FlutterError.onError = (details) {
  if (!(details.exception is OSError) &&
      !(details.exception is HandshakeException) &&
      !(details.exception.runtimeType.toString() == '_Exception') &&
      !(details.exception is SocketException)) {
    onError!(details);
  }
};
Selfassurance answered 31/7, 2023 at 20:33 Comment(0)
A
0
CachedNetworkImage(
                width: 40.0,
                height: 40.0,
                placeholder: (context, url) => const CircularProgressIndicator(),
                imageUrl: '$imageUrl',
                fit: BoxFit.cover,
                errorWidget: (context, url, error) {
                  if (error.toString().contains("404")) {
                    return avatar(firstLetter??"", secondLetter??"");
                  }
                 return avatar(firstLetter??"", secondLetter??"");
                }
              ),
Auxesis answered 31/7, 2024 at 6:6 Comment(0)
H
-4

You could use the Transparent image plugin for this. Link to the Transparent image pub page

Example code: (Taken from the Transparent image page)

    FadeInImage.memoryNetwork(
    placeholder: kTransparentImage,
    image: 'https://picsum.photos/250?image=9',
  ),
);

Hope this is what you needed.

Hoagland answered 20/6, 2020 at 20:44 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.