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

Unified Diff: lib/src/errors.dart

Issue 928663003: Add IsolateRunner as a helper around Isolate. (Closed) Base URL: https://github.com/dart-lang/isolate.git@master
Patch Set: Add .status. Created 5 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/runner.dart ('k') | lib/src/functionref.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/errors.dart
diff --git a/lib/src/errors.dart b/lib/src/errors.dart
new file mode 100644
index 0000000000000000000000000000000000000000..91abe5b568bda67f1a8b464516bc5489109e9049
--- /dev/null
+++ b/lib/src/errors.dart
@@ -0,0 +1,188 @@
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// TODO(lrn): This should be in package:async?
+/**
+ * Helper functions for working with errors.
+ *
+ * The [MultiError] class combines multiple errors into one object,
+ * and the [MultiError.wait] function works like [Future.wait] except
+ * that it returns all the errors.
+ */
+library pkg.isolate.errors;
+
+import "dart:async";
+
+class MultiError extends Error {
+ // Limits the number of lines included from each error's error message.
+ // A best-effort attempt is made at keeping below this number of lines
+ // in the output.
+ // If there are too many errors, they will all get at least one line.
+ static const int _MAX_LINES = 55;
+ // Minimum number of lines in the toString for each error.
+ static const int _MIN_LINES_PER_ERROR = 1;
+
+ /** The actual errors. */
+ final List errors;
+
+ /**
+ * Create a `MultiError` based on a list of errors.
+ *
+ * The errors represent errors of a number of individual operations.
+ *
+ * The list may contain `null` values, if the index of the error in the
+ * list is useful.
+ */
+ MultiError(this.errors);
+
+ /**
+ * Waits for all [futures] to complete, like [Future.wait].
+ *
+ * Where `Future.wait` only reports one error, even if multiple
+ * futures complete with errors, this function will complete
+ * with a [MultiError] if more than one future completes with an error.
+ *
+ * The order of values is not preserved (if that is needed, use
+ * [wait]).
+ */
+ static Future<List> waitUnordered(Iterable<Future> futures,
+ {cleanUp(successResult)}) {
+ Completer completer;
+ int count = 0;
+ int errors = 0;
+ int values = 0;
+ // Initilized to `new List(count)` when count is known.
+ // Filled up with values on the left, errors on the right.
+ // Order is not preserved.
+ List results;
+ void checkDone() {
+ if (errors + values < count) return;
+ if (errors == 0) {
+ completer.complete(results);
+ return;
+ }
+ var errorList = results.sublist(results.length - errors);
+ completer.completeError(new MultiError(errorList));
+ };
+ var handleValue = (v) {
+ // If this fails because [results] is null, there is a future
+ // which breaks the Future API by completing immediately when
+ // calling Future.then, probably by misusing a synchronous completer.
+ results[values++] = v;
+ if (errors > 0 && cleanUp != null) {
+ new Future.sync(() => cleanUp(v));
+ }
+ checkDone();
+ };
+ var handleError = (e, s) {
+ if (errors == 0 && cleanUp != null) {
+ for (int i = 0; i < values; i++) {
+ var value = results[i];
+ if (value != null) new Future.sync(() => cleanUp(value));
+ }
+ }
+ results[results.length - ++errors] = e;
+ checkDone();
+ };
+ for (Future future in futures) {
+ count++;
+ future.then(handleValue, onError: handleError);
+ }
+ if (count == 0) return new Future.value(new List(0));
+ results = new List(count);
+ completer = new Completer();
+ return completer.future;
+ }
+
+ /**
+ * Waits for all [futures] to complete, like [Future.wait].
+ *
+ * Where `Future.wait` only reports one error, even if multiple
+ * futures complete with errors, this function will complete
+ * with a [MultiError] if more than one future completes with an error.
+ *
+ * The order of values is preserved, and if any error occurs, the
+ * [MultiError.errors] list will have errors in the corresponding slots,
+ * and `null` for non-errors.
+ */
+ Future<List> wait(Iterable<Future> futures,
+ {cleanUp(successResult)}) {
+ Completer completer;
+ int count = 0;
+ bool hasError = false;
+ int completed = 0;
+ // Initalized to `new List(count)` when count is known.
+ // Filled with values until the first error, then cleared
+ // and filled with errors.
+ List results;
+ void checkDone() {
+ completed++;
+ if (completed < count) return;
+ if (!hasError) {
+ completer.complete(results);
+ return;
+ }
+ completer.completeError(new MultiError(results));
+ };
+ for (Future future in futures) {
+ int i = count;
+ count++;
+ future.then((v) {
+ if (!hasError) {
+ results[i] = v;
+ } else if (cleanUp != null) {
+ new Future.sync(() => cleanUp(v));
+ }
+ checkDone();
+ }, onError: (e, s) {
+ if (!hasError) {
+ if (cleanUp != null) {
+ for (int i = 0; i < results.length; i++) {
+ var result = results[i];
+ if (result != null) new Future.sync(() => cleanUp(result));
+ }
+ }
+ results.fillRange(0, results.length, null);
+ hasError = true;
+ }
+ results[i] = e;
+ checkDone();
+ });
+ }
+ if (count == 0) return new Future.value(new List(0));
+ results = new List(count);
+ completer = new Completer();
+ return completer.future;
+ }
+
+
+ String toString() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write("Multiple Errors:\n");
+ int linesPerError = _MAX_LINES ~/ errors.length;
+ if (linesPerError < _MIN_LINES_PER_ERROR) {
+ linesPerError = _MIN_LINES_PER_ERROR;
+ }
+
+ for (int index = 0; index < errors.length; index++) {
+ var error = errors[index];
+ if (error == null) continue;
+ String errorString = error.toString();
+ int end = 0;
+ for (int i = 0; i < linesPerError; i++) {
+ end = errorString.indexOf('\n', end) + 1;
+ if (end == 0) {
+ end = errorString.length;
+ break;
+ }
+ }
+ buffer.write("#$index: ");
+ buffer.write(errorString.substring(0, end));
+ if (end < errorString.length) {
+ buffer.write("...\n");
+ }
+ }
+ return buffer.toString();
+ }
+}
« no previous file with comments | « lib/runner.dart ('k') | lib/src/functionref.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698