Image.network 即使在Flutter中定义errorBuilder后仍抛出错误

tpxzln5u  于 2023-03-09  发布在  Flutter
关注(0)|答案(1)|浏览(275)

我在Flutter中从URL加载图像时遇到了一些问题。下面是我的代码:

@override
  Widget build(BuildContext context) {
    return ClipRRect(
      borderRadius: BorderRadius.circular(8.0),
      child: Center(
        child: Image.network(
          'https://www.example.com/no-image.jpg', // this image doesn't exist
          fit: BoxFit.cover,
          errorBuilder: (context, error, stackTrace) {
            return Container(
              color: Colors.amber,
              alignment: Alignment.center,
              child: const Text(
                'Whoops!',
                style: TextStyle(fontSize: 30),
              ),
            );
          },
        ),

      ),
    );
  }

我使用Image.network从一个给定的URL接收图像,但是由于该URL不存在,即使定义了errorBuilder参数,小部件也会抛出一个404异常。
异常源(flutter文件:.../_network_image_io.dart):

Future<ui.Codec> _loadAsync(
    NetworkImage key,
    StreamController<ImageChunkEvent> chunkEvents,
    image_provider.DecoderCallback decode,
  ) async {
    try {
      assert(key == this);

      final Uri resolved = Uri.base.resolve(key.url);

      final HttpClientRequest request = await _httpClient.getUrl(resolved);

      headers?.forEach((String name, String value) {
        request.headers.add(name, value);
      });
      final HttpClientResponse response = await request.close();
      if (response.statusCode != HttpStatus.ok) {
        // The network may be only temporarily unavailable, or the file will be
        // added on the server later. Avoid having future calls to resolve
        // fail to check the network again.
        await response.drain<List<int>>(<int>[]);
        throw image_provider.NetworkImageLoadException(
            statusCode: response.statusCode, uri: resolved);
      }

      final Uint8List bytes = await consolidateHttpClientResponseBytes(
        response,
        onBytesReceived: (int cumulative, int? total) {
          chunkEvents.add(ImageChunkEvent(
            cumulativeBytesLoaded: cumulative,
            expectedTotalBytes: total,
          ));
        },
      );
      if (bytes.lengthInBytes == 0)
        throw Exception('NetworkImage is an empty file: $resolved');

      return decode(bytes);
    } catch (e) {
      // Depending on where the exception was thrown, the image cache may not
      // have had a chance to track the key in the cache at all.
      // Schedule a microtask to give the cache a chance to add the key.
      scheduleMicrotask(() {
        PaintingBinding.instance!.imageCache!.evict(key);
      });
      print(e);
      rethrow; // <<<<<<<< Exception throw here: NetworkImageLoadException (HTTP request failed, statusCode: 404, https://www.example.com/no-image.jpg)
    } finally {
      chunkEvents.close();
    }
  }

我在想是不是有什么问题,或者我弄错了。

enxuqcxy

enxuqcxy1#

是的,您的实现是正确的。问题是,NetworkImage尝试加载图像,但加载失败。因此,_loadAsync()方法rethrows是异常。现在,由于您提供了errorBuilder,框架使用该小部件来显示异常发生的时间。因此,您将获得一个从框架重新引发的异常,但该异常的处理方式与您提供的errorBuilder相同。现在,如果您删除errorBuilder,则会在调试控制台中记录该异常,以及用户,将能够在调试模式下看到红色异常屏幕,在发布模式下看到灰色屏幕。
因此,您对实现和您的怀疑都是正确的,但是您错过了对errorBuilder的确切解释。
我希望这能让你明白自己的疑虑!

相关问题