Skip to content

Failure of ImageProvider's error handling #44579

Description

@slightfoot

@escamoteur and I have been working on an app and a bug in our revealed a whole set of issues within the framework for handling image errors. A bug in our app tried to load a Image file with zero-byte file size which causes the follow chain of events to occur.

Chain of events

  1. ImageProvider.resolve sets up a uncaught exception handler and calls obtainKey and load on FileImage to load the image codec. The way it handles errors here seems very complicated for what is actually required.
  2. FileImage.load is called and creates a MultiFrameImageStreamCompleter and returns it with the codec loading asynchronously.
  3. FileImage._loadAsync later returns a null when it detects the 0 length file.
  4. MultiFrameImageStreamCompleter constructor had setup an error handler for codec loading failures; however because null is reported as a successful response the value is passed to MultiFrameImageStreamCompleter._handleCodecReady which asserts that it can't be null. Because this function does not return a Future the assertion is passed down and caught by our uncaught exception handler rather than by the actual codec failure handler. Secondly this codec failure handler gobbles the error and does not pass it down to the ImageStream?
  5. The uncaught exception is passed over to be handled by ImageProvider.resolve.handleError which then further attempts to set the completer on the ImageStream to its own to error completer which further causes an assertion because a ImageStreams completer can only be set once, and it was previously successfully set by the synchronous load callback;

Thoughts

There are several failures in this chain.. all of which should never have occurred. I am happy to address these as bugs, but to be honest it seems as though a rethink of how ImageProvider errors are handled is probably in order.

It should also be possible to handle these errors gracefully and not silently from within the Image widget. I think we've needed a errorBuilder on it for a long time, and since we now have an error listener as part of ImageCompleter it should be accessible to the end developer.

Steps to Reproduce

Run the example code below in Debug mode of your IDE.

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart' as pp;

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final tmp = await pp.getTemporaryDirectory();
  final blank = await File(p.join(tmp.path, 'test.jpg')).create(recursive: true);
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Example'),
        ),
        body: Center(
          child: Image.file(blank),
        ),
      ),
    ),
  );
}

Logs

[√] Flutter (Channel dev, v1.10.15, on Microsoft Windows [Version 10.0.17763.805], locale en-GB)
    • Flutter version 1.10.15 at C:\Android\flutter
    • Framework revision fbabb264e0 (10 days ago), 2019-11-02 01:36:07 +0300
    • Engine revision 8ea19b1c76
    • Dart version 2.6.0 (build 2.6.0-dev.8.2 bbe2ac28c9)

[√] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
    • Android SDK at C:\Android\SDK
    • Android NDK location not configured (optional; useful for native profiling support)
    • Platform android-29, build-tools 29.0.2
    • ANDROID_HOME = C:\Android\SDK
    • Java binary at: C:\Android\Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[√] Android Studio (version 3.5)
    • Android Studio at C:\Android\Studio
    • Flutter plugin version 39.0.3
    • Dart plugin version 191.8423
    • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b03)

[√] IntelliJ IDEA Ultimate Edition (version 2019.2)
    • IntelliJ at C:\Users\Simon\AppData\Local\JetBrains\Toolbox\apps\IDEA-U\ch-0\192.6817.14
    • Flutter plugin version 39.0.4
    • Dart plugin version 192.6527

[√] VS Code, 64-bit edition (version 1.27.2)
    • VS Code at C:\Program Files\Microsoft VS Code
    • Flutter extension version 2.18.0

[√] Connected device (3 available)
    • iPhone     • 192.168.188.108:5555 • android-x86    • Android 8.0.0 (API 26)
    • Chrome     • chrome               • web-javascript • Google Chrome 78.0.3904.87
    • Web Server • web-server           • web-javascript • Flutter Tools

• No issues found!

Activity

  1. removed their assignment
    on Nov 11, 2019
  2. added
    a: error messageError messages from the Flutter framework
    a: imagesLoading, displaying, rendering images
    on Nov 12, 2019
  3. JamesMcIntosh commented on Dec 2, 2019

    @JamesMcIntosh

    Hi @slightfoot, in point 4 you talk about the assert, in production it will continue over this assert which results in the following error.

    NoSuchMethodError: The method 'getNextFrame' was called on null.
    Receiver: null
    Tried calling: getNextFrame()
    image_stream.dart in MultiFrameImageStreamCompleter._decodeNextFrameAndSchedule at line 680
    Called from: <asynchronous suspension>
    image_stream.dart in MultiFrameImageStreamCompleter._handleCodecReady at line 644
    Called from: zone.dart in _rootRunUnary
    image_provider.dart in FileImage._loadAsync
    Called from: <asynchronous suspension>
    image_provider.dart in FileImage.load at line 530
    image_provider.dart in ImageProvider.resolve.<fn>.<fn>.<fn> at line 316
    image_cache.dart in ImageCache.putIfAbsent at line 160
    image_provider.dart in ImageProvider.resolve.<fn>.<fn> at line 316
    synchronous_future.dart in SynchronousFuture.then at line 38
    image_provider.dart in ImageProvider.resolve.<fn> at line 313
    Called from: zone.dart in _rootRun
    image_provider.dart in ImageProvider.resolve at line 305
    
  4. kw2019ltd commented on Jan 26, 2020

    @kw2019ltd

    same issue multiple times

    Non-fatal Exception: java.lang.Exception: NoSuchMethodError: The method 'getNextFrame' was called on null.
    Receiver: null
    Tried calling: getNextFrame()
    at MultiFrameImageStreamCompleter._decodeNextFrameAndSchedule(image_stream.dart:680)
    at MultiFrameImageStreamCompleter._handleCodecReady(image_stream.dart:644)
    at FileImage._loadAsync(image_provider.dart)
    at FileImage.load(image_provider.dart:638)
    at ImageProvider.resolve...(image_provider.dart:327)
    at ImageCache.putIfAbsent(image_cache.dart:160)
    at ImageProvider.resolve..(image_provider.dart:325)
    at SynchronousFuture.then(synchronous_future.dart:38)
    at ImageProvider.resolve.(image_provider.dart:323)
    at ImageProvider.resolve(image_provider.dart:315)
    at _ImageState._resolveImage(image.dart:1010)
    at _ImageState.didChangeDependencies(image.dart:967)
    at StatefulElement._firstBuild(framework.dart:4376)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at ParentDataElement.mount(framework.dart:4617)
    at Element.inflateWidget(framework.dart:3194)
    at MultiChildRenderObjectElement.mount(framework.dart:5551)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at StatefulElement._firstBuild(framework.dart:4381)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at StatefulElement._firstBuild(framework.dart:4381)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at StatefulElement._firstBuild(framework.dart:4381)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at StatefulElement._firstBuild(framework.dart:4381)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at MultiChildRenderObjectElement.mount(framework.dart:5551)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at StatefulElement._firstBuild(framework.dart:4381)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at StatefulElement._firstBuild(framework.dart:4381)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at MultiChildRenderObjectElement.mount(framework.dart:5551)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at StatefulElement._firstBuild(framework.dart:4381)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at StatefulElement._firstBuild(framework.dart:4381)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at StatefulElement._firstBuild(framework.dart:4381)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at MultiChildRenderObjectElement.mount(framework.dart:5551)
    at _ViewportElement.mount(viewport.dart:186)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at StatefulElement._firstBuild(framework.dart:4381)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at SingleChildRenderObjectElement.mount(framework.dart:5445)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at StatefulElement._firstBuild(framework.dart:4381)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at StatefulElement._firstBuild(framework.dart:4381)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at ComponentElement.performRebuild(framework.dart:4243)
    at Element.rebuild(framework.dart:3947)
    at ComponentElement._firstBuild(framework.dart:4206)
    at ComponentElement.mount(framework.dart:4201)
    at Element.inflateWidget(framework.dart:3194)
    at Element.updateChild(framework.dart:2988)
    at _LayoutBuilderElement._layout.(layout_builder.dart:115)
    at BuildOwner.buildScope(framework.dart:2412)
    at _LayoutBuilderElement._layout(layout_builder.dart:95)
    at RenderObject.invokeLayoutCallback.(object.dart:1823)
    at PipelineOwner._enableMutationsToDirtySubtrees(object.dart:875)
    at RenderObject.invokeLayoutCallback(object.dart:1823)
    at RenderConstrainedLayoutBuilder.layoutAndBuildChild(layout_builder.dart:173)
    at _RenderLayoutBuilder.performLayout(layout_builder.dart:240)
    at RenderObject.layout(object.dart:1724)
    at RenderProxyBoxMixin.performLayout(proxy_box.dart:105)
    at RenderObject.layout(object.dart:1724)
    at MultiChildLayoutDelegate.layoutChild(custom_layout.dart:163)
    at _ScaffoldLayout.performLayout(scaffold.dart:477)
    at MultiChildLayoutDelegate._callPerformLayout(custom_layout.dart:232)
    at RenderCustomMultiChildLayoutBox.performLayout(custom_layout.dart:391)
    at RenderObject._layoutWithoutResize(object.dart:1584)
    at PipelineOwner.flushLayout(object.dart:844)
    at RendererBinding.drawFrame(binding.dart:344)
    at WidgetsBinding.drawFrame(binding.dart:774)
    at RendererBinding._handlePersistentFrameCallback(binding.dart:283)
    at SchedulerBinding._invokeFrameCallback(binding.dart:1102)
    at SchedulerBinding.handleDrawFrame(binding.dart:1041)
    at SchedulerBinding._handleDrawFrame(binding.dart:957)

  5. dnfield commented on Feb 7, 2020

    @dnfield
    Contributor

    I believe the fix for this is to just throw if the file is zero length rather than returning null. That should trigger the expected error handling to kick in. Am I missing something?

  6. dnfield commented on Feb 7, 2020

    @dnfield
    Contributor

    Ah - I fixed part of this in #50242 - unintentionally. But the rest of the fix is to throw instead of returning null.

  7. self-assigned this
    on Feb 7, 2020
  8. added this to the February 2020 milestone on Feb 7, 2020
  9. escamoteur commented on Mar 12, 2020

    @escamoteur
    Contributor

    @dnfield I don't think just throwing is the solution because the Exception is swallowed by the 'Image' so it can't be handled on the WidgetTree level see #19993.
    The right way would be to have an ErrorBuilder in Image that received the exception.

  10. removed this from the February 2020 milestone on Mar 12, 2020
  11. dnfield commented on Mar 12, 2020

    @dnfield
    Contributor

    Ahhh.

    We should probably add onError to

    return ImageStreamListener(
    and pipe that up through the widget.

  12. dnfield commented on Mar 12, 2020

    @dnfield
    Contributor

    And in all fairness, the bug was opened against ImageProvider, not the Image widget. The errorBuilder is a perfectly reasonable request, but I hope it's understandable why I closed it for the ImageProvider related fixes.

  13. escamoteur commented on Mar 19, 2020

    @escamoteur
    Contributor

    @dnfield What is strange, that if I select 'break on uncaught exceptions' in VS code, the debugger breaks on Image errors before it calls the new errorBuilder.

  14. dnfield commented on Mar 19, 2020

    @dnfield
    Contributor

    It probably has something to do with the way the zones are set up and where the error handling occurs. The errors can get thrown in a lot of different ways (sync, async, into the zone wrapping image loading, into the zone above it). This is a real exception though, and if nothing else it's getting handled by the zone handler that propagates it back to error builder.

  15. escamoteur commented on Mar 19, 2020

    @escamoteur
    Contributor

    Yeah but the error builder catches it or not?

  16. dnfield commented on Mar 19, 2020

    @dnfield
    Contributor

    Image decoding is run in a separate zone - there's a zone error handler set up in image_cache.dart that's catching it. But it's catching it in a way the debugger probably doesn't handle (it's not a regular try..catch block, it's a zone error handler).

  17. escamoteur commented on Mar 19, 2020

    @escamoteur
    Contributor

    So we can't do anything tere?

  18. dnfield commented on Mar 19, 2020

    @dnfield
    Contributor

    I'm not clear on what the issue is - if you're concerned about breaking on uncaught exceptions and don't want to break here, then you should fix your code up locally so it doesn't throw an exception (e.g. make sure the image is available and valid).

    If you're concerned that this isn't getting propagated to the error handler, please share a test case and we can try to fix it.

    If it's something else entirely, I'm just missing it and could use some help :)

  19. escamoteur commented on Mar 20, 2020

    @escamoteur
    Contributor

    Ok, the first one :-) in that case I would have to call a File.Exists before which isn't ideal either but I get your point

  20. lock commented on Apr 4, 2020

    @lock

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  21. locked and limited conversation to collaborators on Apr 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

a: error messageError messages from the Flutter frameworka: imagesLoading, displaying, rendering imagescustomer: wednesdayHump day Q&Aframeworkflutter/packages/flutter repository. See also f: labels.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions