"'canvasChartWidth' has not been initialized" error when setting time-range in Memory tab
Reproduced with latest master of DevTools and also DevTools released with Dart 3.5.0.
When setting one of the values of:
- 1 Minute
- 5 Minutes
- 10 Minutes
In the Memory tab:
Then the graph does seem to be updated for the new range but the button are not updated to show what range we have selected. If we select "Default" or "All", the button does get updated.
Looking in the logs, I observe an error are being thrown. After setting up DevTools to run as Windows application, I got the following stacktrace:
flutter: [ERROR]: [zoneGuarded]: LateInitializationError: Field 'canvasChartWidth' has not been initialized.
flutter: [ERROR]: [PlatformDispatcher]: LateInitializationError: Field 'canvasChartWidth' has not been initialized.
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: LateInitializationError: Field 'canvasChartWidth' has not been initialized.
#0 ChartController.canvasChartWidth (package:devtools_app/src/shared/charts/chart_controller.dart)
#1 ChartController.zoomDuration= (package:devtools_app/src/shared/charts/chart_controller.dart:253:24)
#2 _IntervalDropdownState.build.<anonymous closure>.<anonymous closure> (package:devtools_app/src/screens/memory/panes/chart/widgets/interval_dropdown.dart:52:42)
#3 State.setState (package:flutter/src/widgets/framework.dart:1203:30)
#4 _IntervalDropdownState.build.<anonymous closure> (package:devtools_app/src/screens/memory/panes/chart/widgets/interval_dropdown.dart:42:9)
#5 _DropdownButtonState._handleTap.<anonymous closure> (package:flutter/src/material/dropdown.dart:1418:25)
#6 _rootRunUnary (dart:async/zone.dart:1407:47)
#7 _CustomZone.runUnary (dart:async/zone.dart:1308:19)
#8 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:861:45)
#9 Future._propagateToListeners (dart:async/future_impl.dart:890:13)
#10 Future._completeWithValue (dart:async/future_impl.dart:666:5)
#11 Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:736:7)
#12 _rootRun (dart:async/zone.dart:1399:13)
#13 _CustomZone.run (dart:async/zone.dart:1301:19)
#14 _CustomZone.runGuarded (dart:async/zone.dart:1209:7)
#15 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1249:23)
#16 _microtaskLoop (dart:async/schedule_microtask.dart:40:21)
#17 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5)
Which seems to make sense since if we look at the code: https://github.com/flutter/devtools/blob/52cfc6cce3ecab3820b9a96342291d10de8946f7/packages/devtools_app/lib/src/shared/charts/chart_controller.dart#L212-L266
We can see that the code makes use of the late defined variable canvasChartWidth:
https://github.com/flutter/devtools/blob/52cfc6cce3ecab3820b9a96342291d10de8946f7/packages/devtools_app/lib/src/shared/charts/chart_controller.dart#L90-L91
Which are only being set when running the computeChartArea() method which are being executed AFTER set zoomDuration are done running. Which makes us request a late field before it got initialized.
https://github.com/flutter/devtools/blob/52cfc6cce3ecab3820b9a96342291d10de8946f7/packages/devtools_app/lib/src/shared/charts/chart_controller.dart#L399-L420
All of this only happens if we select a range which are not "Default" or "All" since we in those cases does not need the canvasChartWidth value.
Tested with Dart 3.7.0 that comes with DevTools version 2.42.2 and issue can still be reproduced.