| 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 stack_trace.chain; | 5 library stack_trace.chain; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import 'frame.dart'; | 10 import 'frame.dart'; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 /// accessed using [new Chain.current]. Any errors that would be top-leveled in | 28 /// accessed using [new Chain.current]. Any errors that would be top-leveled in |
| 29 /// the zone can be handled, along with their associated chains, with the | 29 /// the zone can be handled, along with their associated chains, with the |
| 30 /// `onError` callback. For example: | 30 /// `onError` callback. For example: |
| 31 /// | 31 /// |
| 32 /// Chain.capture(() { | 32 /// Chain.capture(() { |
| 33 /// // ... | 33 /// // ... |
| 34 /// }, onError: (error, stackChain) { | 34 /// }, onError: (error, stackChain) { |
| 35 /// print("Caught error $error\n" | 35 /// print("Caught error $error\n" |
| 36 /// "$stackChain"); | 36 /// "$stackChain"); |
| 37 /// }); | 37 /// }); |
| 38 /// | |
| 39 /// For the most part [Chain.capture] will notice when an error is thrown and | |
| 40 /// associate the correct stack chain with it; the chain can be accessed using | |
| 41 /// [new Chain.forTrace]. However, there are some cases where exceptions won't | |
| 42 /// be automatically detected: any [Future] constructor, | |
| 43 /// [Completer.completeError], [Stream.addError], and libraries that use these. | |
| 44 /// For these, all you need to do is wrap the Future or Stream in a call to | |
| 45 /// [Chain.track] and the errors will be tracked correctly. | |
| 46 class Chain implements StackTrace { | 38 class Chain implements StackTrace { |
| 47 /// The line used in the string representation of stack chains to represent | 39 /// The line used in the string representation of stack chains to represent |
| 48 /// the gap between traces. | 40 /// the gap between traces. |
| 49 static const _GAP = '===== asynchronous gap ===========================\n'; | 41 static const _GAP = '===== asynchronous gap ===========================\n'; |
| 50 | 42 |
| 51 /// The stack traces that make up this chain. | 43 /// The stack traces that make up this chain. |
| 52 /// | 44 /// |
| 53 /// Like the frames in a stack trace, the traces are ordered from most local | 45 /// Like the frames in a stack trace, the traces are ordered from most local |
| 54 /// to least local. The first one is the trace where the actual exception was | 46 /// to least local. The first one is the trace where the actual exception was |
| 55 /// raised, the second one is where that callback was scheduled, and so on. | 47 /// raised, the second one is where that callback was scheduled, and so on. |
| 56 final List<Trace> traces; | 48 final List<Trace> traces; |
| 57 | 49 |
| 58 /// The [StackZoneSpecification] for the current zone. | 50 /// The [StackZoneSpecification] for the current zone. |
| 59 static StackZoneSpecification get _currentSpec => | 51 static StackZoneSpecification get _currentSpec => |
| 60 Zone.current[#stack_trace.stack_zone.spec]; | 52 Zone.current[#stack_trace.stack_zone.spec]; |
| 61 | 53 |
| 62 /// Runs [callback] in a [Zone] in which the current stack chain is tracked | 54 /// Runs [callback] in a [Zone] in which the current stack chain is tracked |
| 63 /// and automatically associated with (most) errors. | 55 /// and automatically associated with (most) errors. |
| 64 /// | 56 /// |
| 65 /// If [onError] is passed, any error in the zone that would otherwise go | 57 /// If [onError] is passed, any error in the zone that would otherwise go |
| 66 /// unhandled is passed to it, along with the [Chain] associated with that | 58 /// unhandled is passed to it, along with the [Chain] associated with that |
| 67 /// error. Note that if [callback] produces multiple unhandled errors, | 59 /// error. Note that if [callback] produces multiple unhandled errors, |
| 68 /// [onError] may be called more than once. If [onError] isn't passed, the | 60 /// [onError] may be called more than once. If [onError] isn't passed, the |
| 69 /// parent Zone's `unhandledErrorHandler` will be called with the error and | 61 /// parent Zone's `unhandledErrorHandler` will be called with the error and |
| 70 /// its chain. | 62 /// its chain. |
| 71 /// | 63 /// |
| 72 /// For the most part an error thrown in the zone will have the correct stack | |
| 73 /// chain associated with it. However, there are some cases where exceptions | |
| 74 /// won't be automatically detected: any [Future] constructor, | |
| 75 /// [Completer.completeError], [Stream.addError], and libraries that use | |
| 76 /// these. For these, all you need to do is wrap the Future or Stream in a | |
| 77 /// call to [Chain.track] and the errors will be tracked correctly. | |
| 78 /// | |
| 79 /// Note that even if [onError] isn't passed, this zone will still be an error | 64 /// Note that even if [onError] isn't passed, this zone will still be an error |
| 80 /// zone. This means that any errors that would cross the zone boundary are | 65 /// zone. This means that any errors that would cross the zone boundary are |
| 81 /// considered unhandled. | 66 /// considered unhandled. |
| 82 /// | 67 /// |
| 83 /// If [callback] returns a value, it will be returned by [capture] as well. | 68 /// If [callback] returns a value, it will be returned by [capture] as well. |
| 84 /// | 69 /// |
| 85 /// Currently, capturing stack chains doesn't work when using dart2js due to | 70 /// Currently, capturing stack chains doesn't work when using dart2js due to |
| 86 /// issues [15171] and [15105]. Stack chains reported on dart2js will contain | 71 /// issues [15171] and [15105]. Stack chains reported on dart2js will contain |
| 87 /// only one trace. | 72 /// only one trace. |
| 88 /// | 73 /// |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 } | 179 } |
| 195 | 180 |
| 196 /// Converts [this] to a [Trace]. | 181 /// Converts [this] to a [Trace]. |
| 197 /// | 182 /// |
| 198 /// The trace version of a chain is just the concatenation of all the traces | 183 /// The trace version of a chain is just the concatenation of all the traces |
| 199 /// in the chain. | 184 /// in the chain. |
| 200 Trace toTrace() => new Trace(flatten(traces.map((trace) => trace.frames))); | 185 Trace toTrace() => new Trace(flatten(traces.map((trace) => trace.frames))); |
| 201 | 186 |
| 202 String toString() => traces.join(_GAP); | 187 String toString() => traces.join(_GAP); |
| 203 } | 188 } |
| OLD | NEW |