[ package:dds ] Fix issue where handling a StateError due to a VM

service connection loss could result in a null JSON RPC response.

This would cause package:vm_service to throw a NoSuchMethodError as it
currently assumes it will never receive a null result in a JSON RPC
response.

Related to https://github.com/flutter/flutter/issues/74051.

Change-Id: I86c1c9f7e46e34519f32dfed589c6b31aed39d7f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/179800
Reviewed-by: Zach Anderson <zra@google.com>
Commit-Queue: Ben Konyi <bkonyi@google.com>
This commit is contained in:
Ben Konyi 2021-01-17 23:08:18 +00:00 committed by commit-bot@chromium.org
parent 5e66c2b1a1
commit 6de68d541a
4 changed files with 18 additions and 9 deletions

View file

@ -1,3 +1,7 @@
# 1.7.2
- Fixed issue where a null JSON RPC result could be sent if the VM service
disconnected with a request in flight (see https://github.com/flutter/flutter/issues/74051).
# 1.7.1
- Fixed issue where DartDevelopmentServiceException could have a null message.

View file

@ -266,12 +266,14 @@ class DartDevelopmentServiceClient {
// Unless otherwise specified, the request is forwarded to the VM service.
// NOTE: This must be the last fallback registered.
_clientPeer.registerFallback((parameters) async {
try {
return await _vmServicePeer.sendRequest(
parameters.method, parameters.value);
} on StateError {
await dds.shutdown();
}
// If _vmServicePeer closes in the middle of a request, this will throw
// a StateError that will be forwarded to the requesting client.
// Listeners in dds_impl.dart will handle shutting down the DDS, so
// we don't try and handle the error here.
return await _vmServicePeer.sendRequest(
parameters.method,
parameters.value,
);
});
}

View file

@ -3,7 +3,7 @@ description: >-
A library used to spawn the Dart Developer Service, used to communicate with
a Dart VM Service instance.
version: 1.7.1
version: 1.7.2
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds

View file

@ -29,6 +29,9 @@ class StreamCancelDisconnectPeer extends FakePeer {
completer.completeError(
StateError('The client closed with pending request "foo".'),
);
doneCompleter.completeError(
StateError('The client closed with pending request "foo".'),
);
break;
default:
completer.complete(await super.sendRequest(method, args));
@ -83,8 +86,8 @@ void main() {
// unexpectedly.
try {
await client.sendRequest('foo');
} on StateError {
// This state error is expected. This test is ensuring that DDS exits
} on json_rpc.RpcException {
// This RPC exception is expected. This test is ensuring that DDS exits
// gracefully even if the VM service disappears.
}