| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 library error_group; | 5 library error_group; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'utils.dart'; | 9 import 'utils.dart'; |
| 10 | 10 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 _streams.add(wrapped); | 96 _streams.add(wrapped); |
| 97 return wrapped; | 97 return wrapped; |
| 98 } | 98 } |
| 99 | 99 |
| 100 /// Sends [error] to all members of [this]. Like errors that come from | 100 /// Sends [error] to all members of [this]. Like errors that come from |
| 101 /// members, this will only be passed to the top-level error handler if no | 101 /// members, this will only be passed to the top-level error handler if no |
| 102 /// members have listeners. | 102 /// members have listeners. |
| 103 /// | 103 /// |
| 104 /// If all members of [this] have already completed successfully or with an | 104 /// If all members of [this] have already completed successfully or with an |
| 105 /// error, it's a [StateError] to try to signal an error. | 105 /// error, it's a [StateError] to try to signal an error. |
| 106 void signalError(AsyncError error) { | 106 void signalError(var error) { |
| 107 if (_isDone) { | 107 if (_isDone) { |
| 108 throw new StateError("Can't signal errors on a complete ErrorGroup."); | 108 throw new StateError("Can't signal errors on a complete ErrorGroup."); |
| 109 } | 109 } |
| 110 | 110 |
| 111 _signalError(error); | 111 _signalError(error); |
| 112 } | 112 } |
| 113 | 113 |
| 114 /// Signal an error internally. This is just like [signalError], but instead | 114 /// Signal an error internally. This is just like [signalError], but instead |
| 115 /// of throwing an error if [this] is complete, it just does nothing. | 115 /// of throwing an error if [this] is complete, it just does nothing. |
| 116 void _signalError(AsyncError error) { | 116 void _signalError(var error) { |
| 117 if (_isDone) return; | 117 if (_isDone) return; |
| 118 | 118 |
| 119 var caught = false; | 119 var caught = false; |
| 120 for (var future in _futures) { | 120 for (var future in _futures) { |
| 121 if (future._isDone || future._hasListeners) caught = true; | 121 if (future._isDone || future._hasListeners) caught = true; |
| 122 future._signalError(error); | 122 future._signalError(error); |
| 123 } | 123 } |
| 124 | 124 |
| 125 for (var stream in _streams) { | 125 for (var stream in _streams) { |
| 126 if (stream._isDone || stream._hasListeners) caught = true; | 126 if (stream._isDone || stream._hasListeners) caught = true; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 174 if (!_isDone) _completer.complete(value); | 174 if (!_isDone) _completer.complete(value); |
| 175 _isDone = true; | 175 _isDone = true; |
| 176 _group._signalFutureComplete(this); | 176 _group._signalFutureComplete(this); |
| 177 }).catchError((error) => _group._signalError(error)); | 177 }).catchError((error) => _group._signalError(error)); |
| 178 | 178 |
| 179 // Make sure _completer.future doesn't automatically send errors to the | 179 // Make sure _completer.future doesn't automatically send errors to the |
| 180 // top-level. | 180 // top-level. |
| 181 _completer.future.catchError((_) {}); | 181 _completer.future.catchError((_) {}); |
| 182 } | 182 } |
| 183 | 183 |
| 184 Future then(onValue(value), {onError(AsyncError asyncError)}) { | 184 Future then(onValue(value), {onError(error)}) { |
| 185 _hasListeners = true; | 185 _hasListeners = true; |
| 186 return _completer.future.then(onValue, onError: onError); | 186 return _completer.future.then(onValue, onError: onError); |
| 187 } | 187 } |
| 188 | 188 |
| 189 Future catchError(onError(AsyncError asyncError), {bool test(Object error)}) { | 189 Future catchError(onError(error), {bool test(Object error)}) { |
| 190 _hasListeners = true; | 190 _hasListeners = true; |
| 191 return _completer.future.catchError(onError, test: test); | 191 return _completer.future.catchError(onError, test: test); |
| 192 } | 192 } |
| 193 | 193 |
| 194 Future whenComplete(void action()) { | 194 Future whenComplete(void action()) { |
| 195 _hasListeners = true; | 195 _hasListeners = true; |
| 196 return _completer.future.whenComplete(action); | 196 return _completer.future.whenComplete(action); |
| 197 } | 197 } |
| 198 | 198 |
| 199 Stream asStream() { | 199 Stream asStream() { |
| 200 _hasListeners = true; | 200 _hasListeners = true; |
| 201 return _completer.future.asStream(); | 201 return _completer.future.asStream(); |
| 202 } | 202 } |
| 203 | 203 |
| 204 /// Signal that an error from [_group] should be propagated through [this], | 204 /// Signal that an error from [_group] should be propagated through [this], |
| 205 /// unless it's already complete. | 205 /// unless it's already complete. |
| 206 void _signalError(AsyncError error) { | 206 void _signalError(var error) { |
| 207 if (!_isDone) _completer.completeError(error.error, error.stackTrace); | 207 if (!_isDone) _completer.completeError(error); |
| 208 _isDone = true; | 208 _isDone = true; |
| 209 } | 209 } |
| 210 } | 210 } |
| 211 | 211 |
| 212 // TODO(nweiz): currently streams never top-level unhandled errors (issue 7843). | 212 // TODO(nweiz): currently streams never top-level unhandled errors (issue 7843). |
| 213 // When this is fixed, this class will need to prevent such errors from being | 213 // When this is fixed, this class will need to prevent such errors from being |
| 214 // top-leveled. | 214 // top-leveled. |
| 215 /// A [Stream] wrapper that keeps track of whether it's been completed and | 215 /// A [Stream] wrapper that keeps track of whether it's been completed and |
| 216 /// whether it has any listeners. It also notifies its parent [ErrorGroup] when | 216 /// whether it has any listeners. It also notifies its parent [ErrorGroup] when |
| 217 /// it completes successfully or receives an error. | 217 /// it completes successfully or receives an error. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 243 }, onError: (e) { | 243 }, onError: (e) { |
| 244 _group._signalError(e); | 244 _group._signalError(e); |
| 245 }, onDone: () { | 245 }, onDone: () { |
| 246 _isDone = true; | 246 _isDone = true; |
| 247 _group._signalStreamComplete(this); | 247 _group._signalStreamComplete(this); |
| 248 _controller.close(); | 248 _controller.close(); |
| 249 }); | 249 }); |
| 250 } | 250 } |
| 251 | 251 |
| 252 StreamSubscription listen(void onData(value), | 252 StreamSubscription listen(void onData(value), |
| 253 {void onError(AsyncError error), void onDone(), | 253 {void onError(var error), void onDone(), |
| 254 bool cancelOnError}) { | 254 bool cancelOnError}) { |
| 255 return _controller.stream.listen(onData, | 255 return _controller.stream.listen(onData, |
| 256 onError: onError, | 256 onError: onError, |
| 257 onDone: onDone, | 257 onDone: onDone, |
| 258 cancelOnError: true); | 258 cancelOnError: true); |
| 259 } | 259 } |
| 260 | 260 |
| 261 /// Signal that an error from [_group] should be propagated through [this], | 261 /// Signal that an error from [_group] should be propagated through [this], |
| 262 /// unless it's already complete. | 262 /// unless it's already complete. |
| 263 void _signalError(AsyncError e) { | 263 void _signalError(var e) { |
| 264 if (_isDone) return; | 264 if (_isDone) return; |
| 265 _subscription.cancel(); | 265 _subscription.cancel(); |
| 266 // Call these asynchronously to work around issue 7913. | 266 // Call these asynchronously to work around issue 7913. |
| 267 new Future.immediate(null).then((_) { | 267 new Future.immediate(null).then((_) { |
| 268 _controller.addError(e.error, e.stackTrace); | 268 _controller.addError(e); |
| 269 _controller.close(); | 269 _controller.close(); |
| 270 }); | 270 }); |
| 271 } | 271 } |
| 272 } | 272 } |
| OLD | NEW |