Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

Commit 67d07a6

Browse files
[flutter_tools] Fix parsing of existing DDS URIs from exceptions (#119506)
* [flutter_tools] Fix parsing of existing DDS URIs from exceptions Fixes #118609. * Fix formatting Co-authored-by: Christopher Fujino <[email protected]> * Fix formatting Co-authored-by: Christopher Fujino <[email protected]> --------- Co-authored-by: Christopher Fujino <[email protected]>
1 parent df0ab40 commit 67d07a6

File tree

2 files changed

+82
-3
lines changed

2 files changed

+82
-3
lines changed

packages/flutter_tools/lib/src/base/dds.dart

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,21 @@ class DartDevelopmentService {
7171
logger.printTrace('Warning: Failed to start DDS: ${e.message}');
7272
if (e.errorCode == dds.DartDevelopmentServiceException.existingDdsInstanceError) {
7373
try {
74-
_existingDdsUri = Uri.parse(
75-
e.message.split(' ').firstWhere((String e) => e.startsWith('http'))
76-
);
74+
// First try to use the new field to avoid parsing from the message.
75+
_existingDdsUri = e is dds.ExistingDartDevelopmentServiceException ? e.ddsUri : null;
76+
77+
// Otherwise, fall back to parsing from the exception (old DDS).
78+
// This is not completely reliable which is why the new field above
79+
// was added.
80+
if (_existingDdsUri == null) {
81+
String parsedUrl = e.message.split(' ').firstWhere((String e) => e.startsWith('http'));
82+
// Trim trailing full stops from the message.
83+
// https://github.com/flutter/flutter/issues/118609.
84+
if (parsedUrl.endsWith('.')) {
85+
parsedUrl = parsedUrl.substring(0, parsedUrl.length - 1);
86+
}
87+
_existingDdsUri ??= Uri.parse(parsedUrl);
88+
}
7789
} on StateError {
7890
if (e.message.contains('Existing VM service clients prevent DDS from taking control.')) {
7991
throwToolExit('${e.message}. Please rebuild your application with a newer version of Flutter.');

packages/flutter_tools/test/general.shard/resident_runner_test.dart

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2158,6 +2158,73 @@ flutter:
21582158
}) async => FakeVmServiceHost(requests: <VmServiceExpectation>[]).vmService,
21592159
}));
21602160

2161+
testUsingContext('Uses existing DDS URI from exception field', () => testbed.run(() async {
2162+
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
2163+
final FakeDevice device = FakeDevice()
2164+
..dds = DartDevelopmentService();
2165+
ddsLauncherCallback = (Uri uri, {bool enableAuthCodes = true, bool ipv6 = false, Uri? serviceUri, List<String> cachedUserTags = const <String>[], dds.UriConverter? uriConverter}) {
2166+
throw dds.DartDevelopmentServiceException.existingDdsInstance(
2167+
'Existing DDS at http://localhost/existingDdsInMessage.',
2168+
ddsUri: Uri.parse('http://localhost/existingDdsInField'),
2169+
);
2170+
};
2171+
final TestFlutterDevice flutterDevice = TestFlutterDevice(
2172+
device,
2173+
observatoryUris: Stream<Uri>.value(testUri),
2174+
);
2175+
final Completer<void> done = Completer<void>();
2176+
await runZonedGuarded(
2177+
() => flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete()),
2178+
(_, __) => done.complete(),
2179+
);
2180+
await done.future;
2181+
expect(device.dds.uri, Uri.parse('http://localhost/existingDdsInField'));
2182+
}, overrides: <Type, Generator>{
2183+
VMServiceConnector: () => (Uri httpUri, {
2184+
ReloadSources? reloadSources,
2185+
Restart? restart,
2186+
CompileExpression? compileExpression,
2187+
GetSkSLMethod? getSkSLMethod,
2188+
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
2189+
io.CompressionOptions? compression,
2190+
Device? device,
2191+
required Logger logger,
2192+
}) async => FakeVmServiceHost(requests: <VmServiceExpectation>[]).vmService,
2193+
}));
2194+
2195+
testUsingContext('Falls back to existing DDS URI from exception message', () => testbed.run(() async {
2196+
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
2197+
final FakeDevice device = FakeDevice()
2198+
..dds = DartDevelopmentService();
2199+
ddsLauncherCallback = (Uri uri, {bool enableAuthCodes = true, bool ipv6 = false, Uri? serviceUri, List<String> cachedUserTags = const <String>[], dds.UriConverter? uriConverter}) {
2200+
throw dds.DartDevelopmentServiceException.existingDdsInstance(
2201+
'Existing DDS at http://localhost/existingDdsInMessage.',
2202+
);
2203+
};
2204+
final TestFlutterDevice flutterDevice = TestFlutterDevice(
2205+
device,
2206+
observatoryUris: Stream<Uri>.value(testUri),
2207+
);
2208+
final Completer<void>done = Completer<void>();
2209+
await runZonedGuarded(
2210+
() => flutterDevice.connect(allowExistingDdsInstance: true).then((_) => done.complete()),
2211+
(_, __) => done.complete(),
2212+
);
2213+
await done.future;
2214+
expect(device.dds.uri, Uri.parse('http://localhost/existingDdsInMessage'));
2215+
}, overrides: <Type, Generator>{
2216+
VMServiceConnector: () => (Uri httpUri, {
2217+
ReloadSources? reloadSources,
2218+
Restart? restart,
2219+
CompileExpression? compileExpression,
2220+
GetSkSLMethod? getSkSLMethod,
2221+
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
2222+
io.CompressionOptions? compression,
2223+
Device? device,
2224+
required Logger logger,
2225+
}) async => FakeVmServiceHost(requests: <VmServiceExpectation>[]).vmService,
2226+
}));
2227+
21612228
testUsingContext('Host VM service ipv6 defaults', () => testbed.run(() async {
21622229
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
21632230
final FakeDevice device = FakeDevice()

0 commit comments

Comments
 (0)