I use Image.network() to show image from URL this is how I use it
Image image = Image.network(
_auth.currentUser!.photoURL!,
width: 100.getWidth(context),
height: 100.getWidth(context),
frameBuilder: (context, child, frame, wasSynchronouslyLoaded) {
return wasSynchronouslyLoaded
? child
: _profileImagePlaceholder(context);
},
loadingBuilder: (context, child, loadingProgress) {
return loadingProgress == null
? child
: _profileImagePlaceholder(context);
},
errorBuilder: (context, error, stackTrace) {
return _profileImagePlaceholder(context);
},
);
But even when I set errorBuilder or even wrap the whole thing with try/catch
This NetworkImageLoadException
still show
Full Exception
The following NetworkImageLoadException was thrown resolving an image codec:
HTTP request failed, statusCode: 403,
When the exception was thrown, this was the stack:
#0 NetworkImage._loadAsync (package:flutter/src/painting/_network_image_io.dart:99:9)
<asynchronous suspension>
...
Image provider:
NetworkImage("https://firebasestorage.googleapis.com/v0/b/biddee-co.appspot.com/o/profiles%2FdefaultProfile.png?alt=media&token=a4a99031-aabd-4597-b075-77ecb2d3e594",
scale: 1.0)
Image key:
NetworkImage("https://firebasestorage.googleapis.com/v0/b/biddee-co.appspot.com/o/profiles%2FdefaultProfile.png?alt=media&token=a4a99031-aabd-4597-b075-77ecb2d3e594",
scale: 1.0)
In my case, what fixed it in production code was to add a listener in the image resolve with a onError
:
final image = Image.network(
// Properties.
errorBuilder: // ...,
);
image.image.resolve(ImageConfiguration.empty).addListener(
ImageStreamListener(
(_, __) { /* You can do something when the image is loaded. */ },
onError: (_, __) {
// Evict the object from the cache to retry to fetch it the next
// time this widget is built.
imageCache.evict(image.image);
},
),
);
While this works fine in debug / prod, in the tests where I used HttpOverrides.runZoned()
with a client that always returns 404, the tests were always failing with an uncaught NetworkImageLoadException.
The fix was to listen to FlutterError at the beginning of the test and only throw if the exception caught was not a NetworkImageLoadException
.
WidgetsFlutterBinding.ensureInitialized();
FlutterError.onError = (details) {
if (details.exception is! NetworkImageLoadException) throw details.exception;
};