[flutter_tools] Collect more information in ios-handshake failure event (#50804)

diff --git a/packages/flutter_tools/lib/src/ios/fallback_discovery.dart b/packages/flutter_tools/lib/src/ios/fallback_discovery.dart
index c4cbf60..cf8883f 100644
--- a/packages/flutter_tools/lib/src/ios/fallback_discovery.dart
+++ b/packages/flutter_tools/lib/src/ios/fallback_discovery.dart
@@ -120,13 +120,19 @@
     } on Exception catch (err) {
       _logger.printTrace(err.toString());
       _logger.printTrace('Failed to connect directly, falling back to mDNS');
-      UsageEvent(_kEventName, 'failure').send();
+      UsageEvent(
+        _kEventName,
+        'failure',
+        label: err.toString(),
+        value: hostPort,
+      ).send();
       return null;
     }
 
     // Attempt to connect to the VM service 5 times.
     int attempts = 0;
     const int kDelaySeconds = 2;
+    Object firstException;
     while (attempts < 5) {
       try {
         final VmService vmService = await _vmServiceConnectUri(assumedWsUri.toString());
@@ -145,6 +151,7 @@
         }
       } on Exception catch (err) {
         // No action, we might have failed to connect.
+        firstException ??= err;
         _logger.printTrace(err.toString());
       }
 
@@ -156,7 +163,12 @@
       attempts += 1;
     }
     _logger.printTrace('Failed to connect directly, falling back to mDNS');
-    UsageEvent(_kEventName, 'failure').send();
+    UsageEvent(
+      _kEventName,
+      'failure',
+      label: firstException?.toString() ?? 'Connection attempts exhausted',
+      value: hostPort,
+    ).send();
     return null;
   }
 }
diff --git a/packages/flutter_tools/test/general.shard/ios/devices_test.dart b/packages/flutter_tools/test/general.shard/ios/devices_test.dart
index 4a09c95..b30b9ee 100644
--- a/packages/flutter_tools/test/general.shard/ios/devices_test.dart
+++ b/packages/flutter_tools/test/general.shard/ios/devices_test.dart
@@ -384,7 +384,12 @@
             debuggingOptions: DebuggingOptions.enabled(const BuildInfo(BuildMode.debug, null, treeShakeIcons: false)),
             platformArgs: <String, dynamic>{},
         );
-        verify(mockUsage.sendEvent('ios-handshake', 'failure')).called(1);
+        verify(mockUsage.sendEvent(
+          'ios-handshake',
+          'failure',
+          label: anyNamed('label'),
+          value: anyNamed('value'),
+        )).called(1);
         verify(mockUsage.sendEvent('ios-handshake', 'mdns-failure')).called(1);
         verify(mockUsage.sendEvent('ios-handshake', 'fallback-failure')).called(1);
         expect(launchResult.started, isFalse);