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); |
} |
} |