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

Side by Side Diff: packages/isolate/lib/src/errors.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 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
« no previous file with comments | « packages/isolate/lib/runner.dart ('k') | packages/isolate/lib/src/lists.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
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.
4
5 // TODO(lrn): This should be in package:async?
6 /// Helper functions for working with errors.
7 ///
8 /// The [MultiError] class combines multiple errors into one object,
9 /// and the [MultiError.wait] function works like [Future.wait] except
10 /// that it returns all the errors.
11 library isolate.errors;
12
13 import 'dart:async';
14
15 class MultiError extends Error {
16 // Limits the number of lines included from each error's error message.
17 // A best-effort attempt is made at keeping below this number of lines
18 // in the output.
19 // If there are too many errors, they will all get at least one line.
20 static const int _MAX_LINES = 55;
21 // Minimum number of lines in the toString for each error.
22 static const int _MIN_LINES_PER_ERROR = 1;
23
24 /// The actual errors.
25 final List errors;
26
27 /// Create a `MultiError` based on a list of errors.
28 ///
29 /// The errors represent errors of a number of individual operations.
30 ///
31 /// The list may contain `null` values, if the index of the error in the
32 /// list is useful.
33 MultiError(this.errors);
34
35 /// Waits for all [futures] to complete, like [Future.wait].
36 ///
37 /// Where `Future.wait` only reports one error, even if multiple
38 /// futures complete with errors, this function will complete
39 /// with a [MultiError] if more than one future completes with an error.
40 ///
41 /// The order of values is not preserved (if that is needed, use
42 /// [wait]).
43 static Future<List> waitUnordered(Iterable<Future> futures,
44 {cleanUp(successResult)}) {
45 Completer completer;
46 int count = 0;
47 int errors = 0;
48 int values = 0;
49 // Initialized to `new List(count)` when count is known.
50 // Filled up with values on the left, errors on the right.
51 // Order is not preserved.
52 List results;
53 void checkDone() {
54 if (errors + values < count) return;
55 if (errors == 0) {
56 completer.complete(results);
57 return;
58 }
59 var errorList = results.sublist(results.length - errors);
60 completer.completeError(new MultiError(errorList));
61 };
62 var handleValue = (v) {
63 // If this fails because [results] is null, there is a future
64 // which breaks the Future API by completing immediately when
65 // calling Future.then, probably by misusing a synchronous completer.
66 results[values++] = v;
67 if (errors > 0 && cleanUp != null) {
68 new Future.sync(() => cleanUp(v));
69 }
70 checkDone();
71 };
72 var handleError = (e, s) {
73 if (errors == 0 && cleanUp != null) {
74 for (int i = 0; i < values; i++) {
75 var value = results[i];
76 if (value != null) new Future.sync(() => cleanUp(value));
77 }
78 }
79 results[results.length - ++errors] = e;
80 checkDone();
81 };
82 for (Future future in futures) {
83 count++;
84 future.then(handleValue, onError: handleError);
85 }
86 if (count == 0) return new Future.value(new List(0));
87 results = new List(count);
88 completer = new Completer();
89 return completer.future;
90 }
91
92 /// Waits for all [futures] to complete, like [Future.wait].
93 ///
94 /// Where `Future.wait` only reports one error, even if multiple
95 /// futures complete with errors, this function will complete
96 /// with a [MultiError] if more than one future completes with an error.
97 ///
98 /// The order of values is preserved, and if any error occurs, the
99 /// [MultiError.errors] list will have errors in the corresponding slots,
100 /// and `null` for non-errors.
101 Future<List> wait(Iterable<Future> futures, {cleanUp(successResult)}) {
102 Completer completer;
103 int count = 0;
104 bool hasError = false;
105 int completed = 0;
106 // Initialized to `new List(count)` when count is known.
107 // Filled with values until the first error, then cleared
108 // and filled with errors.
109 List results;
110 void checkDone() {
111 completed++;
112 if (completed < count) return;
113 if (!hasError) {
114 completer.complete(results);
115 return;
116 }
117 completer.completeError(new MultiError(results));
118 };
119 for (Future future in futures) {
120 int i = count;
121 count++;
122 future.then((v) {
123 if (!hasError) {
124 results[i] = v;
125 } else if (cleanUp != null) {
126 new Future.sync(() => cleanUp(v));
127 }
128 checkDone();
129 }, onError: (e, s) {
130 if (!hasError) {
131 if (cleanUp != null) {
132 for (int i = 0; i < results.length; i++) {
133 var result = results[i];
134 if (result != null) new Future.sync(() => cleanUp(result));
135 }
136 }
137 results.fillRange(0, results.length, null);
138 hasError = true;
139 }
140 results[i] = e;
141 checkDone();
142 });
143 }
144 if (count == 0) return new Future.value(new List(0));
145 results = new List(count);
146 completer = new Completer();
147 return completer.future;
148 }
149
150 String toString() {
151 StringBuffer buffer = new StringBuffer();
152 buffer.write("Multiple Errors:\n");
153 int linesPerError = _MAX_LINES ~/ errors.length;
154 if (linesPerError < _MIN_LINES_PER_ERROR) {
155 linesPerError = _MIN_LINES_PER_ERROR;
156 }
157
158 for (int index = 0; index < errors.length; index++) {
159 var error = errors[index];
160 if (error == null) continue;
161 String errorString = error.toString();
162 int end = 0;
163 for (int i = 0; i < linesPerError; i++) {
164 end = errorString.indexOf('\n', end) + 1;
165 if (end == 0) {
166 end = errorString.length;
167 break;
168 }
169 }
170 buffer.write("#$index: ");
171 buffer.write(errorString.substring(0, end));
172 if (end < errorString.length) {
173 buffer.write("...\n");
174 }
175 }
176 return buffer.toString();
177 }
178 }
OLDNEW
« no previous file with comments | « packages/isolate/lib/runner.dart ('k') | packages/isolate/lib/src/lists.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698