super_editor icon indicating copy to clipboard operation
super_editor copied to clipboard

[BUG] - TypeError: type 'Null' is not a subtype of type 'DocumentLayout' in type cast

Open quaaantumdev opened this issue 1 year ago • 6 comments

Package Version super_editor, GitHub, stable branch (#d519ae5247f7bcfa1722d75ab3c92fc8804bf1d9)

User Info "individual"

To Reproduce not sure but the SuperReader was placed inside a CustomScrollView and the orientation of the device changed to landscape right before the exception occured. So i suppose it must be something to do with the orientation change.

Minimal Reproduction Code If the bug is reproducible in the Example app, you can delete this section. Otherwise, please provide a minimal, runnable code reproduction.

Actual behavior The following exception occured:

TypeError: type 'Null' is not a subtype of type 'DocumentLayout' in type cast
  File "super_reader.dart", line 317, in SuperReaderState._createReaderContext.<fn>
  File "framework.dart", line 5593, in ComponentElement.mount
  File "framework.dart", line 4468, in Element.inflateWidget
  File "framework.dart", line 3963, in Element.updateChild
  File "framework.dart", line 6900, in SingleChildRenderObjectElement.mount
  File "framework.dart", line 4468, in Element.inflateWidget
  File "framework.dart", line 3963, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5780, in StatefulElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5599, in ComponentElement._firstBuild
  File "framework.dart", line 5771, in StatefulElement._firstBuild
  File "framework.dart", line 5593, in ComponentElement.mount
  File "framework.dart", line 4468, in Element.inflateWidget
  File "framework.dart", line 3963, in Element.updateChild
  File "framework.dart", line 6900, in SingleChildRenderObjectElement.mount
  File "framework.dart", line 4468, in Element.inflateWidget
  File "framework.dart", line 3963, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5599, in ComponentElement._firstBuild
  File "framework.dart", line 5593, in ComponentElement.mount
  File "framework.dart", line 4468, in Element.inflateWidget
  File "framework.dart", line 3963, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5780, in StatefulElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5599, in ComponentElement._firstBuild
  File "framework.dart", line 5771, in StatefulElement._firstBuild
  File "framework.dart", line 5593, in ComponentElement.mount
  File "framework.dart", line 4468, in Element.inflateWidget
  File "framework.dart", line 3963, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5599, in ComponentElement._firstBuild
  File "framework.dart", line 5593, in ComponentElement.mount
  File "framework.dart", line 4468, in Element.inflateWidget
  File "framework.dart", line 3963, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5599, in ComponentElement._firstBuild
  File "framework.dart", line 5593, in ComponentElement.mount
  File "framework.dart", line 4468, in Element.inflateWidget
  File "framework.dart", line 3963, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5599, in ComponentElement._firstBuild
  File "framework.dart", line 5593, in ComponentElement.mount
  File "framework.dart", line 4468, in Element.inflateWidget
  File "framework.dart", line 3963, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5780, in StatefulElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5599, in ComponentElement._firstBuild
  File "framework.dart", line 5771, in StatefulElement._firstBuild
  File "framework.dart", line 5593, in ComponentElement.mount
  File "framework.dart", line 4468, in Element.inflateWidget
  File "framework.dart", line 3957, in Element.updateChild
  File "framework.dart", line 6907, in SingleChildRenderObjectElement.update
  File "framework.dart", line 3941, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5946, in ProxyElement.update
  File "inherited_provider.dart", line 523, in _InheritedProviderScopeElement.update
  File "framework.dart", line 3941, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5693, in StatelessElement.update
  File "framework.dart", line 3941, in Element.updateChild
  File "framework.dart", line 6907, in SingleChildRenderObjectElement.update
  File "framework.dart", line 3941, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5780, in StatefulElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5803, in StatefulElement.update
  File "framework.dart", line 3941, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5780, in StatefulElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5803, in StatefulElement.update
  File "framework.dart", line 3941, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5693, in StatelessElement.update
  File "framework.dart", line 3941, in Element.updateChild
  File "framework.dart", line 4090, in Element.updateChildren
  File "framework.dart", line 7060, in MultiChildRenderObjectElement.update
  File "framework.dart", line 3941, in Element.updateChild
  File "slotted_render_object_widget.dart", line 223, in SlottedRenderObjectElement._updateChild
  File "slotted_render_object_widget.dart", line 213, in SlottedRenderObjectElement._updateChildren
  File "slotted_render_object_widget.dart", line 192, in SlottedRenderObjectElement.update
  File "framework.dart", line 3941, in Element.updateChild
  File "framework.dart", line 6907, in SingleChildRenderObjectElement.update
  File "framework.dart", line 3941, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5693, in StatelessElement.update
  File "framework.dart", line 3941, in Element.updateChild
  File "framework.dart", line 5642, in ComponentElement.performRebuild
  File "framework.dart", line 5333, in Element.rebuild
  File "framework.dart", line 5693, in StatelessElement.update
  File "framework.dart", line 3941, in Element.updateChild
  File "layout_builder.dart", line 207, in _LayoutBuilderElement._rebuildWithConstraints.updateChildCallback
  File "framework.dart", line 3038, in BuildOwner.buildScope
  File "layout_builder.dart", line 231, in _LayoutBuilderElement._rebuildWithConstraints
  File "object.dart", line 2719, in RenderObject.invokeLayoutCallback.<fn>
  File "object.dart", line 1098, in PipelineOwner._enableMutationsToDirtySubtrees
  File "object.dart", line 2719, in RenderObject.invokeLayoutCallback
  File "layout_builder.dart", line 278, in RenderConstrainedLayoutBuilder.rebuildIfNecessary
  File "sliver_layout_builder.dart", line 46, in _RenderSliverLayoutBuilder.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "sliver_padding.dart", line 121, in RenderSliverEdgeInsetsPadding.performLayout
  File "sliver_padding.dart", line 327, in RenderSliverPadding.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "viewport.dart", line 601, in RenderViewportBase.layoutChildSequence
  File "viewport.dart", line 1516, in RenderViewport._attemptLayout
  File "viewport.dart", line 1427, in RenderViewport.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "proxy_box.dart", line 1448, in _RenderCustomClip.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "layout_builder.dart", line 371, in _RenderLayoutBuilder.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 291, in RenderConstrainedBox.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "layout_builder.dart", line 371, in _RenderLayoutBuilder.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "custom_layout.dart", line 173, in MultiChildLayoutDelegate.layoutChild
  File "scaffold.dart", line 1092, in _ScaffoldLayout.performLayout
  File "custom_layout.dart", line 237, in MultiChildLayoutDelegate._callPerformLayout
  File "custom_layout.dart", line 404, in RenderCustomMultiChildLayoutBox.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "proxy_box.dart", line 1448, in _RenderCustomClip.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "proxy_box.dart", line 3728, in RenderOffstage.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "overlay.dart", line 1002, in _RenderTheaterMixin.layoutChild
  File "overlay.dart", line 1311, in _RenderTheater.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "stack.dart", line 510, in RenderStack.layoutPositionedChild
  File "stack.dart", line 635, in RenderStack.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "shifted_box.dart", line 705, in RenderConstrainedOverflowBox.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "stack.dart", line 510, in RenderStack.layoutPositionedChild
  File "stack.dart", line 635, in RenderStack.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "layout_builder.dart", line 371, in _RenderLayoutBuilder.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "custom_layout.dart", line 173, in MultiChildLayoutDelegate.layoutChild
  File "scaffold.dart", line 1092, in _ScaffoldLayout.performLayout
  File "custom_layout.dart", line 237, in MultiChildLayoutDelegate._callPerformLayout
  File "custom_layout.dart", line 404, in RenderCustomMultiChildLayoutBox.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "proxy_box.dart", line 1448, in _RenderCustomClip.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "proxy_box.dart", line 3728, in RenderOffstage.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "overlay.dart", line 1002, in _RenderTheaterMixin.layoutChild
  File "overlay.dart", line 1311, in _RenderTheater.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "proxy_box.dart", line 111, in RenderProxyBoxMixin.performLayout
  File "object.dart", line 2608, in RenderObject.layout
  File "view.dart", line 281, in RenderView.performLayout
  File "object.dart", line 2446, in RenderObject._layoutWithoutResize
  File "object.dart", line 1052, in PipelineOwner.flushLayout
  File "object.dart", line 1065, in PipelineOwner.flushLayout
  File "binding.dart", line 602, in RendererBinding.drawFrame
  File "binding.dart", line 1164, in WidgetsBinding.drawFrame
  File "binding.dart", line 468, in RendererBinding._handlePersistentFrameCallback
  File "binding.dart", line 1397, in SchedulerBinding._invokeFrameCallback
  File "binding.dart", line 1318, in SchedulerBinding.handleDrawFrame
  File "binding.dart", line 1176, in SchedulerBinding._handleDrawFrame
  File "hooks.dart", line 312, in _invoke
  File "platform_dispatcher.dart", line 419, in PlatformDispatcher._drawFrame
  File "hooks.dart", line 283, in _drawFrame

Expected behavior No exception :)

Platform Android 13, Android 14

Flutter version flutter 3.24.1 (not 100% sure but i believe so, maybe one minor version less) dart 3.5.1 (this must be correct)

Additional context I think it must be something with the orientation change, unfortionally i was not yet able to identify the specific issue myself.

i think the actual line in the stacktrace must be off by 1, it must be this line: https://github.com/superlistapp/super_editor/blob/a213ed30104930b52e3870c0b191d3d98f4ced45/super_editor/lib/src/super_reader/super_reader.dart#L318

I found logs from multiple devices, all looking pretty much the same, always with the orientation change. The SuperReader is placed inside a CustomScrollView but i think it does not pop out of view or get into view by changing the device orientation. I also tried to reproduce this issue myself but was not yet able to do so.

quaaantumdev avatar Sep 15 '24 09:09 quaaantumdev

@knopp before I assign this to @angelosilvestre can you let me know if this looks related to slivers at all?

matthew-carroll avatar Sep 25 '24 03:09 matthew-carroll

@knopp checking in again

matthew-carroll avatar Jan 15 '25 19:01 matthew-carroll

It doesn't seem to be.

knopp avatar Jan 15 '25 21:01 knopp

@quaaantumdev Could you share some details of your widget tree? Reading your stacktrace I suppose your are using LayoutBuilders, Stacks, Positioneds, etc... Also, do you still see this issue in more recent SuperEditor versions?

@matthew-carroll So far I haven't been able to reproduce this issue. I tried changing the orientation while moving SuperReader out of the viewport, but I couldn't trigger this error. It seems that the document's layout is, somehow, being unmounted. I tried messing with the keys, but this also didn't trigger it. The DocumentLayout's key never changes once the SuperReader is initialized. I see some StatefulElement._firstBuild calls in the stack trace, maybe some ancestor widgets are changing around SuperReader. Do you have any ideas on what else could I look?

I did find another crash when selecting some content and rotating the device:

════════ Exception caught by scheduler library ═════════════════════════════════
The following _TypeError was thrown during a scheduler callback:
type 'RenderSliverToBoxAdapter' is not a subtype of type 'RenderBox' in type cast

When the exception was thrown, this was the stack:
#0      _ReadOnlyAndroidDocumentTouchInteractorState._ensureSelectionExtentIsVisible (package:super_editor/src/super_reader/read_only_document_android_touch_interactor.dart:325:77)
read_only_document_android_touch_interactor.dart:325
#1      _ReadOnlyAndroidDocumentTouchInteractorState.didChangeMetrics.<anonymous closure> (package:super_editor/src/super_reader/read_only_document_android_touch_interactor.dart:292:7)
read_only_document_android_touch_interactor.dart:292
#2      Frames.onNextFrame.<anonymous closure> (package:super_editor/src/infrastructure/flutter/flutter_scheduler.dart:72:11)
flutter_scheduler.dart:72
#3      SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1442:15)
binding.dart:1442
#4      SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1369:11)
binding.dart:1369
#5      SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1208:5)
binding.dart:1208
#6      _invoke (dart:ui/hooks.dart:316:13)
hooks.dart:316
#7      PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:428:5)
platform_dispatcher.dart:428
#8      _drawFrame (dart:ui/hooks.dart:288:31)
hooks.dart:288
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by scheduler library ═════════════════════════════════
type 'RenderSliverToBoxAdapter' is not a subtype of type 'RenderBox' in type cast

There is a place _ReadOnlyAndroidDocumentTouchInteractorState._ensureSelectionExtentIsVisible we are assuming the the document's RenderObject is a RenderBox, which is no longer the case:

// Determines the offset of the editor in the viewport coordinate
final editorBox = widget.documentKey.currentContext!.findRenderObject() as RenderBox;

angelosilvestre avatar Feb 15 '25 14:02 angelosilvestre

@angelosilvestre if the hypothesis is ancestor widgets then you might try writing a variety of tests that pump and repump with ancestor inherited widgets appearing and disappearing and changing values, etc. Whatever you think might cause the problem. Once we're able to capture something in a test, we can fix it.

Based on some recent experience building a custom element, it's really easy to screw up the necessary implementation that's relevant to ancestor widgets. Especially in cases like ContentLayers where we know we're massively hacking the scoped rebuilds.

I did find another crash when selecting some content and rotating the device

If it's related, let's solve it here. If not, please file a new issue and let's address it there.

matthew-carroll avatar Feb 16 '25 20:02 matthew-carroll

@matthew-carroll I filed https://github.com/superlistapp/super_editor/issues/2580 because that bug will be much more straightforward to fix, while this ticket might be tricky to reproduce.

angelosilvestre avatar Feb 18 '25 22:02 angelosilvestre