| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of service; | 5 part of service; |
| 6 | 6 |
| 7 /// A [ServiceObject] is an object known to the VM service and is tied | 7 /// A [ServiceObject] is an object known to the VM service and is tied |
| 8 /// to an owning [Isolate]. | 8 /// to an owning [Isolate]. |
| 9 abstract class ServiceObject extends Observable { | 9 abstract class ServiceObject extends Observable { |
| 10 /// The owner of this [ServiceObject]. This can be an [Isolate], a | 10 /// The owner of this [ServiceObject]. This can be an [Isolate], a |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 // Cache miss. Get the object from the vm directly. | 277 // Cache miss. Get the object from the vm directly. |
| 278 return getAsMap(id).then((ObservableMap map) { | 278 return getAsMap(id).then((ObservableMap map) { |
| 279 var obj = new ServiceObject._fromMap(this, map); | 279 var obj = new ServiceObject._fromMap(this, map); |
| 280 if (obj.canCache) { | 280 if (obj.canCache) { |
| 281 _cache.putIfAbsent(id, () => obj); | 281 _cache.putIfAbsent(id, () => obj); |
| 282 } | 282 } |
| 283 return obj; | 283 return obj; |
| 284 }); | 284 }); |
| 285 } | 285 } |
| 286 | 286 |
| 287 dynamic _reviver(dynamic key, dynamic value) { |
| 288 return value; |
| 289 } |
| 290 |
| 291 ObservableMap _parseJSON(String response) { |
| 292 var map; |
| 293 try { |
| 294 var decoder = new JsonDecoder(_reviver); |
| 295 map = decoder.convert(response); |
| 296 } catch (e, st) { |
| 297 return null; |
| 298 } |
| 299 return toObservable(map); |
| 300 } |
| 301 |
| 287 Future<ObservableMap> _processMap(ObservableMap map) { | 302 Future<ObservableMap> _processMap(ObservableMap map) { |
| 288 // Verify that the top level response is a service map. | 303 // Verify that the top level response is a service map. |
| 289 if (!_isServiceMap(map)) { | 304 if (!_isServiceMap(map)) { |
| 290 return new Future.error( | 305 return new Future.error( |
| 291 new ServiceObject._fromMap(this, toObservable({ | 306 new ServiceObject._fromMap(this, toObservable({ |
| 292 'type': 'ServiceException', | 307 'type': 'ServiceException', |
| 293 'id': '', | 308 'id': '', |
| 294 'kind': 'FormatException', | 309 'kind': 'FormatException', |
| 295 'response': map, | 310 'response': map, |
| 296 'message': 'Top level service responses must be service maps.', | 311 'message': 'Top level service responses must be service maps.', |
| 297 }))); | 312 }))); |
| 298 } | 313 } |
| 299 // Preemptively capture ServiceError and ServiceExceptions. | 314 // Preemptively capture ServiceError and ServiceExceptions. |
| 300 if (map['type'] == 'ServiceError') { | 315 if (map['type'] == 'ServiceError') { |
| 301 return new Future.error(new ServiceObject._fromMap(this, map)); | 316 return new Future.error(new ServiceObject._fromMap(this, map)); |
| 302 } else if (map['type'] == 'ServiceException') { | 317 } else if (map['type'] == 'ServiceException') { |
| 303 return new Future.error(new ServiceObject._fromMap(this, map)); | 318 return new Future.error(new ServiceObject._fromMap(this, map)); |
| 304 } | 319 } |
| 305 // map is now guaranteed to be a non-error/exception ServiceObject. | 320 // map is now guaranteed to be a non-error/exception ServiceObject. |
| 306 return new Future.value(map); | 321 return new Future.value(map); |
| 307 } | 322 } |
| 308 | 323 |
| 324 Future<ObservableMap> _decodeError(e) { |
| 325 return new Future.error(new ServiceObject._fromMap(this, toObservable({ |
| 326 'type': 'ServiceException', |
| 327 'id': '', |
| 328 'kind': 'DecodeException', |
| 329 'response': |
| 330 'This is likely a result of a known V8 bug. Although the ' |
| 331 'the bug has been fixed the fix may not be in your Chrome' |
| 332 ' version. For more information see dartbug.com/18385. ' |
| 333 'Observatory is still functioning and you should try your' |
| 334 ' action again.', |
| 335 'message': 'Could not decode JSON: $e', |
| 336 }))); |
| 337 } |
| 338 |
| 309 /// Gets [id] as an [ObservableMap] from the service directly. If | 339 /// Gets [id] as an [ObservableMap] from the service directly. If |
| 310 /// an error occurs, the future is completed as an error with a | 340 /// an error occurs, the future is completed as an error with a |
| 311 /// ServiceError or ServiceException. Therefore any chained then() calls | 341 /// ServiceError or ServiceException. Therefore any chained then() calls |
| 312 /// will only receive a map encoding a valid ServiceObject. | 342 /// will only receive a map encoding a valid ServiceObject. |
| 313 Future<ObservableMap> getAsMap(String id) { | 343 Future<ObservableMap> getAsMap(String id) { |
| 314 return getString(id).then((response) { | 344 return getString(id).then((response) { |
| 345 var map; |
| 315 try { | 346 try { |
| 316 var map = toObservable(JSON.decode(response)); | 347 map = _parseJSON(response); |
| 317 return _processMap(map); | |
| 318 } catch (e, st) { | 348 } catch (e, st) { |
| 319 return new Future.error( | 349 print('Hit V8 bug.'); |
| 320 new ServiceObject._fromMap(this, toObservable({ | 350 return _decodeError(e); |
| 321 'type': 'ServiceException', | |
| 322 'id': '', | |
| 323 'kind': 'DecodeException', | |
| 324 'response': | |
| 325 'This is likely a result of a known V8 bug. Although the ' | |
| 326 'the bug has been fixed the fix may not be in your Chrome' | |
| 327 ' version. For more information see dartbug.com/18385. ' | |
| 328 'Observatory is still functioning and you should try your' | |
| 329 ' action again.', | |
| 330 'message': 'Could not decode JSON: $e', | |
| 331 }))); | |
| 332 } | 351 } |
| 352 return _processMap(map); |
| 333 }).catchError((error) { | 353 }).catchError((error) { |
| 334 // ServiceError, forward to VM's ServiceError stream. | 354 // ServiceError, forward to VM's ServiceError stream. |
| 335 errors.add(error); | 355 errors.add(error); |
| 336 return new Future.error(error); | 356 return new Future.error(error); |
| 337 }, test: (e) => e is ServiceError).catchError((exception) { | 357 }, test: (e) => e is ServiceError).catchError((exception) { |
| 338 // ServiceException, forward to VM's ServiceException stream. | 358 // ServiceException, forward to VM's ServiceException stream. |
| 339 exceptions.add(exception); | 359 exceptions.add(exception); |
| 340 return new Future.error(exception); | 360 return new Future.error(exception); |
| 341 }, test: (e) => e is ServiceException); | 361 }, test: (e) => e is ServiceException); |
| 342 } | 362 } |
| (...skipping 1140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1483 var v = list[i]; | 1503 var v = list[i]; |
| 1484 if ((v is ObservableMap) && _isServiceMap(v)) { | 1504 if ((v is ObservableMap) && _isServiceMap(v)) { |
| 1485 list[i] = owner.getFromMap(v); | 1505 list[i] = owner.getFromMap(v); |
| 1486 } else if (v is ObservableList) { | 1506 } else if (v is ObservableList) { |
| 1487 _upgradeObservableList(v, owner); | 1507 _upgradeObservableList(v, owner); |
| 1488 } else if (v is ObservableMap) { | 1508 } else if (v is ObservableMap) { |
| 1489 _upgradeObservableMap(v, owner); | 1509 _upgradeObservableMap(v, owner); |
| 1490 } | 1510 } |
| 1491 } | 1511 } |
| 1492 } | 1512 } |
| OLD | NEW |