| 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 import 'dart:math' as math; | 9 import 'dart:math' as math; |
| 10 | 10 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 /// | 42 /// |
| 43 /// Like the frames in a stack trace, the traces are ordered from most local | 43 /// Like the frames in a stack trace, the traces are ordered from most local |
| 44 /// to least local. The first one is the trace where the actual exception was | 44 /// to least local. The first one is the trace where the actual exception was |
| 45 /// raised, the second one is where that callback was scheduled, and so on. | 45 /// raised, the second one is where that callback was scheduled, and so on. |
| 46 final List<Trace> traces; | 46 final List<Trace> traces; |
| 47 | 47 |
| 48 /// The [StackZoneSpecification] for the current zone. | 48 /// The [StackZoneSpecification] for the current zone. |
| 49 static StackZoneSpecification get _currentSpec => | 49 static StackZoneSpecification get _currentSpec => |
| 50 Zone.current[#stack_trace.stack_zone.spec]; | 50 Zone.current[#stack_trace.stack_zone.spec]; |
| 51 | 51 |
| 52 /// Runs [callback] in a [Zone] in which the current stack chain is tracked | 52 /// If [when] is `true`, runs [callback] in a [Zone] in which the current |
| 53 /// and automatically associated with (most) errors. | 53 /// stack chain is tracked and automatically associated with (most) errors. |
| 54 /// |
| 55 /// If [when] is `false`, this does not track stack chains. Instead, it's |
| 56 /// identical to [runZoned], except that it wraps any errors in [new |
| 57 /// Chain.forTrace]—which will only wrap the trace unless there's a different |
| 58 /// [Chain.capture] active. This makes it easy for the caller to only capture |
| 59 /// stack chains in debug mode or during development. |
| 54 /// | 60 /// |
| 55 /// If [onError] is passed, any error in the zone that would otherwise go | 61 /// If [onError] is passed, any error in the zone that would otherwise go |
| 56 /// unhandled is passed to it, along with the [Chain] associated with that | 62 /// unhandled is passed to it, along with the [Chain] associated with that |
| 57 /// error. Note that if [callback] produces multiple unhandled errors, | 63 /// error. Note that if [callback] produces multiple unhandled errors, |
| 58 /// [onError] may be called more than once. If [onError] isn't passed, the | 64 /// [onError] may be called more than once. If [onError] isn't passed, the |
| 59 /// parent Zone's `unhandledErrorHandler` will be called with the error and | 65 /// parent Zone's `unhandledErrorHandler` will be called with the error and |
| 60 /// its chain. | 66 /// its chain. |
| 61 /// | 67 /// |
| 62 /// Note that even if [onError] isn't passed, this zone will still be an error | 68 /// Note that even if [onError] isn't passed, this zone will still be an error |
| 63 /// zone. This means that any errors that would cross the zone boundary are | 69 /// zone. This means that any errors that would cross the zone boundary are |
| 64 /// considered unhandled. | 70 /// considered unhandled. |
| 65 /// | 71 /// |
| 66 /// If [callback] returns a value, it will be returned by [capture] as well. | 72 /// If [callback] returns a value, it will be returned by [capture] as well. |
| 67 static capture(callback(), {void onError(error, Chain chain)}) { | 73 static capture(callback(), {void onError(error, Chain chain), |
| 74 bool when: true}) { |
| 75 if (!when) { |
| 76 var newOnError; |
| 77 if (onError != null) { |
| 78 newOnError = (error, stackTrace) { |
| 79 onError(error, new Chain.forTrace(stackTrace)); |
| 80 }; |
| 81 } |
| 82 |
| 83 return runZoned(callback, onError: newOnError); |
| 84 } |
| 85 |
| 68 var spec = new StackZoneSpecification(onError); | 86 var spec = new StackZoneSpecification(onError); |
| 69 return runZoned(() { | 87 return runZoned(() { |
| 70 try { | 88 try { |
| 71 return callback(); | 89 return callback(); |
| 72 } catch (error, stackTrace) { | 90 } catch (error, stackTrace) { |
| 73 // TODO(nweiz): Don't special-case this when issue 19566 is fixed. | 91 // TODO(nweiz): Don't special-case this when issue 19566 is fixed. |
| 74 return Zone.current.handleUncaughtError(error, stackTrace); | 92 return Zone.current.handleUncaughtError(error, stackTrace); |
| 75 } | 93 } |
| 76 }, zoneSpecification: spec.toSpec(), zoneValues: { | 94 }, zoneSpecification: spec.toSpec(), zoneValues: { |
| 77 #stack_trace.stack_zone.spec: spec | 95 #stack_trace.stack_zone.spec: spec |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 | 206 |
| 189 // Don't call out to [Trace.toString] here because that doesn't ensure that | 207 // Don't call out to [Trace.toString] here because that doesn't ensure that |
| 190 // padding is consistent across all traces. | 208 // padding is consistent across all traces. |
| 191 return traces.map((trace) { | 209 return traces.map((trace) { |
| 192 return trace.frames.map((frame) { | 210 return trace.frames.map((frame) { |
| 193 return '${padRight(frame.location, longest)} ${frame.member}\n'; | 211 return '${padRight(frame.location, longest)} ${frame.member}\n'; |
| 194 }).join(); | 212 }).join(); |
| 195 }).join(chainGap); | 213 }).join(chainGap); |
| 196 } | 214 } |
| 197 } | 215 } |
| OLD | NEW |