@@ -91,7 +91,7 @@ class HotRunner extends ResidentRunner {
9191 this .multidexEnabled = false ,
9292 super .devtoolsHandler,
9393 StopwatchFactory stopwatchFactory = const StopwatchFactory (),
94- ReloadSourcesHelper reloadSourcesHelper = _defaultReloadSourcesHelper ,
94+ ReloadSourcesHelper reloadSourcesHelper = defaultReloadSourcesHelper ,
9595 ReassembleHelper reassembleHelper = _defaultReassembleHelper,
9696 }) : _stopwatchFactory = stopwatchFactory,
9797 _reloadSourcesHelper = reloadSourcesHelper,
@@ -1174,7 +1174,8 @@ typedef ReloadSourcesHelper = Future<OperationResult> Function(
11741174 String ? reason,
11751175);
11761176
1177- Future <OperationResult > _defaultReloadSourcesHelper (
1177+ @visibleForTesting
1178+ Future <OperationResult > defaultReloadSourcesHelper (
11781179 HotRunner hotRunner,
11791180 List <FlutterDevice ?> flutterDevices,
11801181 bool ? pause,
@@ -1186,18 +1187,21 @@ Future<OperationResult> _defaultReloadSourcesHelper(
11861187) async {
11871188 final Stopwatch vmReloadTimer = Stopwatch ()..start ();
11881189 const String entryPath = 'main.dart.incremental.dill' ;
1189- final List <Future <DeviceReloadReport >> allReportsFutures = < Future <DeviceReloadReport >> [];
1190+ final List <Future <DeviceReloadReport ? >> allReportsFutures = < Future <DeviceReloadReport ? >> [];
11901191
11911192 for (final FlutterDevice ? device in flutterDevices) {
11921193 final List <Future <vm_service.ReloadReport >> reportFutures = await _reloadDeviceSources (
11931194 device! ,
11941195 entryPath,
11951196 pause: pause,
11961197 );
1197- allReportsFutures.add (Future .wait (reportFutures).then (
1198+ allReportsFutures.add (Future .wait (reportFutures).then < DeviceReloadReport ?> (
11981199 (List <vm_service.ReloadReport > reports) async {
11991200 // TODO(aam): Investigate why we are validating only first reload report,
12001201 // which seems to be current behavior
1202+ if (reports.isEmpty) {
1203+ return null ;
1204+ }
12011205 final vm_service.ReloadReport firstReport = reports.first;
12021206 // Don't print errors because they will be printed further down when
12031207 // `validateReloadReport` is called again.
@@ -1208,9 +1212,9 @@ Future<OperationResult> _defaultReloadSourcesHelper(
12081212 },
12091213 ));
12101214 }
1211- final List <DeviceReloadReport > reports = await Future .wait (allReportsFutures);
1212- final vm_service.ReloadReport reloadReport = reports.first.reports[0 ];
1213- if (! HotRunner .validateReloadReport (reloadReport)) {
1215+ final Iterable <DeviceReloadReport > reports = ( await Future .wait (allReportsFutures)). whereType < DeviceReloadReport >( );
1216+ final vm_service.ReloadReport ? reloadReport = reports.isEmpty ? null : reports.first.reports[0 ];
1217+ if (reloadReport == null || ! HotRunner .validateReloadReport (reloadReport)) {
12141218 // Reload failed.
12151219 HotEvent ('reload-reject' ,
12161220 targetPlatform: targetPlatform! ,
@@ -1223,6 +1227,9 @@ Future<OperationResult> _defaultReloadSourcesHelper(
12231227 // Reset devFS lastCompileTime to ensure the file will still be marked
12241228 // as dirty on subsequent reloads.
12251229 _resetDevFSCompileTime (flutterDevices);
1230+ if (reloadReport == null ) {
1231+ return OperationResult (1 , 'No Dart isolates found' );
1232+ }
12261233 final ReloadReportContents contents = ReloadReportContents .fromReloadReport (reloadReport);
12271234 return OperationResult (1 , 'Reload rejected: ${contents .notices .join ("\n " )}' );
12281235 }
0 commit comments