Home > Blockchain >  errorBuilder callback of Image.network not invoked when in DecorationImage
errorBuilder callback of Image.network not invoked when in DecorationImage

Time:06-11

Why does errorBuilder of Image.network not get invoked when in DecorationImage?

Instead error that occurs in Image.network invokes onError of DecorationImage. So I cannot substitute failed image with another widget.

Here is the code with this situation. I took the example from the documentation for errorBuilder and amended it so that Image.network is in DecorationImage. See below:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Flutter Code Sample';

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: _title,
      home: Scaffold(
        body: Center(
          child: MyStatelessWidget(),
        ),
      ),
    );
  }
}

class MyStatelessWidget extends StatelessWidget {
  const MyStatelessWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
          color: Colors.white,
          border: Border.all(),
          borderRadius: BorderRadius.circular(20),
          image: DecorationImage(
              one rror: (obj, st) {
                  print('ONERROR-ONERROR-ONERROR');
              },
              image: Image.network(
                'https://example.does.not.exist/image.jpg',
                errorBuilder:
                    (BuildContext context, Object exception, StackTrace? stackTrace) {
                  // Appropriate logging or analytics, e.g.
                  // myAnalytics.recordError(
                  //   'An error occurred loading "https://example.does.not.exist/image.jpg"',
                  //   exception,
                  //   stackTrace,
                  // );
                  return const Text('ERROR');
                },
              ).image
          )
      ),
      child: const SizedBox(height: 200, width: 200),
    );
  }
}

CodePudding user response:

You are using image:Image.network().image that returns ImageProvider. It means image will get from Image.network only when there is no error and image load perfectly. When the issue happens, you can see onError message.

Now for the use case errorBuilder return a widget that can't be directly assign on image.

This might be call overengineered to handle the error.

 @override
 Widget build(BuildContext context) {
   final dImage = DecorationImage(
     one rror: (obj, st) {
       print('ONERROR-ONERROR-ONERROR');
     },
     image: Image.network(
       'h .exist/image.jpg',
       errorBuilder:
           (BuildContext context, Object exception, StackTrace? stackTrace) {
         debugPrint("onError B");

         return Text("rr");
       },
     ).image,
   );
   return Container(
     decoration: BoxDecoration(
       color: Colors.white,
       border: Border.all(),
       borderRadius: BorderRadius.circular(20),
       image: dImage.onError != null
           ? DecorationImage(
               image: NetworkImage(imgUrl), //default image URL on null case
             )
           : dImage,
     ),
     child: const SizedBox(height: 200, width: 200),
   );
 }

I will prefer using Container child with stack if I need overlay.

We already have child option and simplify the case. This is a simple and cleaner approach you can just tell by reading the code, don't have to scroll the mouse.

return Container(
  height: 200,
  width: 200,
  decoration: BoxDecoration(
    color: Colors.white,
    border: Border.all(),
    borderRadius: BorderRadius.circular(20),
  ),
  child: Image.network(
    'h .exist/image.jpg',
    errorBuilder:
        (BuildContext context, Object exception, StackTrace? stackTrace) {
      debugPrint("onError B");
      return Center(child: Text("Error"));
    },
  ),
);
  • Related