Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(601)

Side by Side Diff: sdk/lib/async/future_impl.dart

Issue 11826050: Consider a thrown AsyncError from a future/stream handler a rethrow. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Add tests. Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sdk/lib/async/future.dart ('k') | sdk/lib/async/stream.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 dart.async; 5 part of dart.async;
6 6
7 deprecatedFutureValue(_FutureImpl future) => 7 deprecatedFutureValue(_FutureImpl future) =>
8 future._isComplete ? future._resultOrListeners : null; 8 future._isComplete ? future._resultOrListeners : null;
9 9
10 10
11 class _CompleterImpl<T> implements Completer<T> { 11 class _CompleterImpl<T> implements Completer<T> {
12 final Future<T> future; 12 final Future<T> future;
13 bool _isComplete = false; 13 bool _isComplete = false;
14 14
15 _CompleterImpl() : future = new _FutureImpl<T>(); 15 _CompleterImpl() : future = new _FutureImpl<T>();
16 16
17 void complete([T value]) { 17 void complete([T value]) {
18 if (_isComplete) throw new StateError("Future already completed"); 18 if (_isComplete) throw new StateError("Future already completed");
19 _isComplete = true; 19 _isComplete = true;
20 _FutureImpl future = this.future; 20 _FutureImpl future = this.future;
21 future._setValue(value); 21 future._setValue(value);
22 } 22 }
23 23
24 void completeError(Object error, [Object stackTrace = null]) { 24 void completeError(Object error, [Object stackTrace = null]) {
25 if (_isComplete) throw new StateError("Future already completed"); 25 if (_isComplete) throw new StateError("Future already completed");
26 _isComplete = true; 26 _isComplete = true;
27 AsyncError asyncError;
28 if (error is AsyncError) {
29 asyncError = error;
30 } else {
31 asyncError = new AsyncError(error, stackTrace);
32 }
33 // Never complete an error in the same cycle. Otherwise users might
34 // not have a chance to register their error-handlers.
27 new Timer(0, (_) { 35 new Timer(0, (_) {
28 // Never complete an error in the same cycle. Otherwise users might
29 // not have a chance to register their error-handlers.
30 _FutureImpl future = this.future; 36 _FutureImpl future = this.future;
31 future._setError(new AsyncError(error, stackTrace)); 37 future._setError(asyncError);
32 }); 38 });
33 } 39 }
34 } 40 }
35 41
36 /** 42 /**
37 * A listener on a future. 43 * A listener on a future.
38 * 44 *
39 * When the future completes, the [_sendValue] or [_sendError] method 45 * When the future completes, the [_sendValue] or [_sendError] method
40 * is invoked with the result. 46 * is invoked with the result.
41 * 47 *
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 var _resultOrListeners; 92 var _resultOrListeners;
87 93
88 _FutureImpl(); 94 _FutureImpl();
89 95
90 _FutureImpl.immediate(T value) { 96 _FutureImpl.immediate(T value) {
91 _state = _VALUE; 97 _state = _VALUE;
92 _resultOrListeners = value; 98 _resultOrListeners = value;
93 } 99 }
94 100
95 _FutureImpl.immediateError(var error, [Object stackTrace]) { 101 _FutureImpl.immediateError(var error, [Object stackTrace]) {
96 new Timer(0, (_) { _setError(new AsyncError(error, stackTrace)); }); 102 AsyncError asyncError;
103 if (error is AsyncError) {
104 asyncError = error;
105 } else {
106 asyncError = new AsyncError(error, stackTrace);
107 }
108 new Timer(0, (_) { _setError(asyncError); });
97 } 109 }
98 110
99 factory _FutureImpl.wait(Iterable<Future> futures) { 111 factory _FutureImpl.wait(Iterable<Future> futures) {
100 // TODO(ajohnsen): can we do better wrt the generic type T? 112 // TODO(ajohnsen): can we do better wrt the generic type T?
101 if (futures.isEmpty) { 113 if (futures.isEmpty) {
102 return new Future<List>.immediate(const []); 114 return new Future<List>.immediate(const []);
103 } 115 }
104 116
105 Completer completer = new Completer<List>(); 117 Completer completer = new Completer<List>();
106 int remaining = futures.length; 118 int remaining = futures.length;
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 // checked mode. 341 // checked mode.
330 final /* _FutureOnValue<S> */ _onValue; 342 final /* _FutureOnValue<S> */ _onValue;
331 343
332 _ThenFuture(this._onValue); 344 _ThenFuture(this._onValue);
333 345
334 _sendValue(S value) { 346 _sendValue(S value) {
335 assert(_onValue != null); 347 assert(_onValue != null);
336 var result; 348 var result;
337 try { 349 try {
338 result = _onValue(value); 350 result = _onValue(value);
351 } on AsyncError catch (e) {
352 _setError(e);
353 return;
339 } catch (e, s) { 354 } catch (e, s) {
340 _setError(new AsyncError(e, s)); 355 _setError(new AsyncError(e, s));
341 return; 356 return;
342 } 357 }
343 _setOrChainValue(result); 358 _setOrChainValue(result);
344 } 359 }
345 360
346 void _sendError(AsyncError error) { 361 void _sendError(AsyncError error) {
347 _setError(error); 362 _setError(error);
348 } 363 }
(...skipping 24 matching lines...) Expand all
373 } 388 }
374 if (!matchesTest) { 389 if (!matchesTest) {
375 _setError(error); 390 _setError(error);
376 return; 391 return;
377 } 392 }
378 } 393 }
379 // Act on the error, and use the result as this future's result. 394 // Act on the error, and use the result as this future's result.
380 var result; 395 var result;
381 try { 396 try {
382 result = _onError(error); 397 result = _onError(error);
398 } on AsyncError catch (e) {
399 _setError(e);
400 return;
383 } catch (e, s) { 401 } catch (e, s) {
384 _setError(new AsyncError.withCause(e, s, error)); 402 _setError(new AsyncError.withCause(e, s, error));
385 return; 403 return;
386 } 404 }
387 _setOrChainValue(result); 405 _setOrChainValue(result);
388 } 406 }
389 } 407 }
390 408
391 /** Future returned by [Future.then] with an [:onError:] parameter. */ 409 /** Future returned by [Future.then] with an [:onError:] parameter. */
392 class _SubscribeFuture<S, T> extends _ThenFuture<S, T> { 410 class _SubscribeFuture<S, T> extends _ThenFuture<S, T> {
393 final _FutureOnError _onError; 411 final _FutureOnError _onError;
394 412
395 _SubscribeFuture(onValue(S value), this._onError) : super(onValue); 413 _SubscribeFuture(onValue(S value), this._onError) : super(onValue);
396 414
397 // The _sendValue method is inherited from ThenFuture. 415 // The _sendValue method is inherited from ThenFuture.
398 416
399 void _sendError(AsyncError error) { 417 void _sendError(AsyncError error) {
400 assert(_onError != null); 418 assert(_onError != null);
401 var result; 419 var result;
402 try { 420 try {
403 result = _onError(error); 421 result = _onError(error);
422 } on AsyncError catch (e) {
423 _setError(e);
424 return;
404 } catch (e, s) { 425 } catch (e, s) {
405 _setError(new AsyncError.withCause(e, s, error)); 426 _setError(new AsyncError.withCause(e, s, error));
406 return; 427 return;
407 } 428 }
408 _setOrChainValue(result); 429 _setOrChainValue(result);
409 } 430 }
410 } 431 }
411 432
412 /** Future returned by [Future.whenComplete]. */ 433 /** Future returned by [Future.whenComplete]. */
413 class _WhenFuture<T> extends _TransformFuture<T, T> { 434 class _WhenFuture<T> extends _TransformFuture<T, T> {
414 final _FutureAction _action; 435 final _FutureAction _action;
415 436
416 _WhenFuture(this._action); 437 _WhenFuture(this._action);
417 438
418 void _sendValue(T value) { 439 void _sendValue(T value) {
419 try { 440 try {
420 var result = _action(); 441 var result = _action();
421 if (result is Future) { 442 if (result is Future) {
422 Future resultFuture = result; 443 Future resultFuture = result;
423 resultFuture.then((_) { 444 resultFuture.then((_) {
424 _setValue(value); 445 _setValue(value);
425 }, onError: _setError); 446 }, onError: _setError);
426 return; 447 return;
427 } 448 }
449 } on AsyncError catch (e) {
450 _setError(e);
451 return;
428 } catch (e, s) { 452 } catch (e, s) {
429 _setError(new AsyncError(e, s)); 453 _setError(new AsyncError(e, s));
430 return; 454 return;
431 } 455 }
432 456
433 _setValue(value); 457 _setValue(value);
434 } 458 }
435 459
436 void _sendError(AsyncError error) { 460 void _sendError(AsyncError error) {
437 try { 461 try {
438 var result = _action(); 462 var result = _action();
439 if (result is Future) { 463 if (result is Future) {
440 Future resultFuture = result; 464 Future resultFuture = result;
441 // TODO(lrn): Find a way to combine [error] into [e]. 465 // TODO(lrn): Find a way to combine [error] into [e].
442 resultFuture.then((_) { 466 resultFuture.then((_) {
443 _setError(error); 467 _setError(error);
444 }, onError: _setError); 468 }, onError: _setError);
445 return; 469 return;
446 } 470 }
471 } on AsyncError catch (e) {
472 _setError(e);
473 return;
447 } catch (e, s) { 474 } catch (e, s) {
448 error = new AsyncError.withCause(e, s, error); 475 error = new AsyncError.withCause(e, s, error);
449 } 476 }
450 _setError(error); 477 _setError(error);
451 } 478 }
452 } 479 }
453 480
454 /** 481 /**
455 * Thin wrapper around a [Future]. 482 * Thin wrapper around a [Future].
456 * 483 *
(...skipping 13 matching lines...) Expand all
470 Future catchError(function(AsyncError error), {bool test(var error)}) { 497 Future catchError(function(AsyncError error), {bool test(var error)}) {
471 return _future.catchError(function, test: test); 498 return _future.catchError(function, test: test);
472 } 499 }
473 500
474 Future<T> whenComplete(action()) { 501 Future<T> whenComplete(action()) {
475 return _future.whenComplete(action); 502 return _future.whenComplete(action);
476 } 503 }
477 504
478 Stream<T> asStream() => new Stream.fromFuture(_future); 505 Stream<T> asStream() => new Stream.fromFuture(_future);
479 } 506 }
OLDNEW
« no previous file with comments | « sdk/lib/async/future.dart ('k') | sdk/lib/async/stream.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698