Handle service disappeared RPCError when VM service connection disappears (#74424)
* Handle service disappeared RPCError when VM service connection disappears while invoking a service extension registered by the framework * Add unit test, handle non-trivial cases
This commit is contained in:
parent
1f07fde45d
commit
08068fd94c
@ -417,6 +417,25 @@ extension FlutterVmService on vm_service.VmService {
|
||||
|
||||
Uri get httpAddress => this != null ? _httpAddressExpando[this] : null;
|
||||
|
||||
Future<vm_service.Response> callMethodWrapper(
|
||||
String method, {
|
||||
String isolateId,
|
||||
Map<String, dynamic> args
|
||||
}) async {
|
||||
try {
|
||||
return await callMethod(method, isolateId: isolateId, args: args);
|
||||
} on vm_service.RPCError catch (e) {
|
||||
// If the service disappears mid-request the tool is unable to recover
|
||||
// and should begin to shutdown due to the service connection closing.
|
||||
// Swallow the exception here and let the shutdown logic elsewhere deal
|
||||
// with cleaning up.
|
||||
if (e.code == RPCErrorCodes.kServiceDisappeared) {
|
||||
return null;
|
||||
}
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the asset directory for the an attached Flutter view.
|
||||
Future<void> setAssetDirectory({
|
||||
@required Uri assetsDirectory,
|
||||
@ -424,7 +443,7 @@ extension FlutterVmService on vm_service.VmService {
|
||||
@required String uiIsolateId,
|
||||
}) async {
|
||||
assert(assetsDirectory != null);
|
||||
await callMethod(kSetAssetBundlePathMethod,
|
||||
await callMethodWrapper(kSetAssetBundlePathMethod,
|
||||
isolateId: uiIsolateId,
|
||||
args: <String, dynamic>{
|
||||
'viewId': viewId,
|
||||
@ -439,12 +458,15 @@ extension FlutterVmService on vm_service.VmService {
|
||||
Future<Map<String, Object>> getSkSLs({
|
||||
@required String viewId,
|
||||
}) async {
|
||||
final vm_service.Response response = await callMethod(
|
||||
final vm_service.Response response = await callMethodWrapper(
|
||||
kGetSkSLsMethod,
|
||||
args: <String, String>{
|
||||
'viewId': viewId,
|
||||
},
|
||||
);
|
||||
if (response == null) {
|
||||
return null;
|
||||
}
|
||||
return response.json['SkSLs'] as Map<String, Object>;
|
||||
}
|
||||
|
||||
@ -454,7 +476,7 @@ extension FlutterVmService on vm_service.VmService {
|
||||
Future<void> flushUIThreadTasks({
|
||||
@required String uiIsolateId,
|
||||
}) async {
|
||||
await callMethod(
|
||||
await callMethodWrapper(
|
||||
kFlushUIThreadTasksMethod,
|
||||
args: <String, String>{
|
||||
'isolateId': uiIsolateId,
|
||||
@ -480,7 +502,7 @@ extension FlutterVmService on vm_service.VmService {
|
||||
final Future<void> onRunnable = onIsolateEvent.firstWhere((vm_service.Event event) {
|
||||
return event.kind == vm_service.EventKind.kIsolateRunnable;
|
||||
});
|
||||
await callMethod(
|
||||
await callMethodWrapper(
|
||||
kRunInViewMethod,
|
||||
args: <String, Object>{
|
||||
'viewId': viewId,
|
||||
@ -745,9 +767,12 @@ extension FlutterVmService on vm_service.VmService {
|
||||
Duration delay = const Duration(milliseconds: 50),
|
||||
}) async {
|
||||
while (true) {
|
||||
final vm_service.Response response = await callMethod(
|
||||
final vm_service.Response response = await callMethodWrapper(
|
||||
kListViewsMethod,
|
||||
);
|
||||
if (response == null) {
|
||||
return null;
|
||||
}
|
||||
final List<Object> rawViews = response.json['views'] as List<Object>;
|
||||
final List<FlutterView> views = <FlutterView>[
|
||||
for (final Object rawView in rawViews)
|
||||
|
@ -312,6 +312,27 @@ void main() {
|
||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||
});
|
||||
|
||||
testWithoutContext('Framework service extension invocations return null if service disappears ', () async {
|
||||
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
|
||||
requests: <VmServiceExpectation>[
|
||||
const FakeVmServiceRequest(method: kGetSkSLsMethod, args: <String, Object>{
|
||||
'viewId': '1234',
|
||||
}, errorCode: RPCErrorCodes.kServiceDisappeared),
|
||||
const FakeVmServiceRequest(method: kListViewsMethod, errorCode: RPCErrorCodes.kServiceDisappeared),
|
||||
]
|
||||
);
|
||||
|
||||
final Map<String, Object> skSLs = await fakeVmServiceHost.vmService.getSkSLs(
|
||||
viewId: '1234',
|
||||
);
|
||||
expect(skSLs, null);
|
||||
|
||||
final List<FlutterView> views = await fakeVmServiceHost.vmService.getFlutterViews();
|
||||
expect(views, null);
|
||||
|
||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||
});
|
||||
|
||||
testWithoutContext('getFlutterViews polls until a view is returned', () async {
|
||||
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
|
||||
requests: <VmServiceExpectation>[
|
||||
|
Loading…
x
Reference in New Issue
Block a user