| Index: runtime/observatory/lib/service_common.dart
|
| diff --git a/runtime/observatory/lib/service_common.dart b/runtime/observatory/lib/service_common.dart
|
| index fe84b207409df3e1c44e6f0fcc593beb1d23fb3f..50774c42c1bd2053056001d0872f59c13bf3c118 100644
|
| --- a/runtime/observatory/lib/service_common.dart
|
| +++ b/runtime/observatory/lib/service_common.dart
|
| @@ -116,6 +116,7 @@ abstract class CommonWebSocketVM extends VM {
|
| }
|
| }
|
| Future get onDisconnect => _disconnected.future;
|
| + bool get isDisconnected => _disconnected.isCompleted;
|
|
|
| void disconnect({String reason : 'WebSocket closed'}) {
|
| if (_hasInitiatedConnect) {
|
| @@ -135,6 +136,11 @@ abstract class CommonWebSocketVM extends VM {
|
| _webSocket.connect(
|
| target.networkAddress, _onOpen, _onMessage, _onError, _onClose);
|
| }
|
| + if (_disconnected.isCompleted) {
|
| + // This connection was closed already.
|
| + var exception = new NetworkRpcException('WebSocket closed');
|
| + return new Future.error(exception);
|
| + }
|
| String serial = (_requestSerial++).toString();
|
| var request = new _WebSocketRequest(method, params);
|
| if (_webSocket.isOpen) {
|
| @@ -173,12 +179,12 @@ abstract class CommonWebSocketVM extends VM {
|
| map = JSON.decode(message);
|
| } catch (e, st) {
|
| Logger.root.severe('Disconnecting: Error decoding message: $e\n$st');
|
| - disconnect(reason:'Error decoding JSON message: $e');
|
| + disconnect(reason:'Connection saw corrupt JSON message: $e');
|
| return null;
|
| }
|
| if (map == null) {
|
| Logger.root.severe("Disconnecting: Unable to decode 'null' message");
|
| - disconnect(reason:"Unable to decode 'null' message");
|
| + disconnect(reason:"Connection saw 'null' message");
|
| return null;
|
| }
|
| return map;
|
| @@ -221,7 +227,6 @@ abstract class CommonWebSocketVM extends VM {
|
|
|
| // Extract serial and result.
|
| var serial = map['id'];
|
| - var result = map['result'];
|
|
|
| // Complete request.
|
| var request = _pendingRequests.remove(serial);
|
| @@ -235,7 +240,14 @@ abstract class CommonWebSocketVM extends VM {
|
| Logger.root.info(
|
| 'RESPONSE [${serial}] ${request.method}');
|
| }
|
| - request.completer.complete(result);
|
| +
|
| + var result = map['result'];
|
| + if (result != null) {
|
| + request.completer.complete(result);
|
| + } else {
|
| + var exception = new ServerRpcException.fromMap(map['error']);
|
| + request.completer.completeError(exception);
|
| + }
|
| }
|
|
|
| // WebSocket message event handler.
|
| @@ -247,33 +259,25 @@ abstract class CommonWebSocketVM extends VM {
|
| }
|
| }
|
|
|
| - Map _generateNetworkError(String userMessage) {
|
| - var response = {
|
| - 'type': 'ServiceException',
|
| - 'kind': 'ConnectionClosed',
|
| - 'message': userMessage,
|
| - };
|
| - return response;
|
| - }
|
| -
|
| void _cancelRequests(Map<String,_WebSocketRequest> requests,
|
| - String reason) {
|
| + String message) {
|
| requests.forEach((_, _WebSocketRequest request) {
|
| - request.completer.complete(
|
| - _generateNetworkError(reason));
|
| + var exception = new NetworkRpcException(message);
|
| + request.completer.completeError(exception);
|
| });
|
| requests.clear();
|
| }
|
|
|
| /// Cancel all pending and delayed requests by completing them with an error.
|
| void _cancelAllRequests(String reason) {
|
| + String message = 'Canceling request: $reason';
|
| if (_pendingRequests.length > 0) {
|
| - Logger.root.info('Cancelling all pending requests.');
|
| - _cancelRequests(_pendingRequests, reason);
|
| + Logger.root.info('Canceling all pending requests.');
|
| + _cancelRequests(_pendingRequests, message);
|
| }
|
| if (_delayedRequests.length > 0) {
|
| - Logger.root.info('Cancelling all delayed requests.');
|
| - _cancelRequests(_delayedRequests, reason);
|
| + Logger.root.info('Canceling all delayed requests.');
|
| + _cancelRequests(_delayedRequests, message);
|
| }
|
| }
|
|
|
|
|