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 19 matching lines...) Expand all Loading... |
30 /// the zone can be handled, along with their associated chains, with the | 30 /// the zone can be handled, along with their associated chains, with the |
31 /// `onError` callback. For example: | 31 /// `onError` callback. For example: |
32 /// | 32 /// |
33 /// Chain.capture(() { | 33 /// Chain.capture(() { |
34 /// // ... | 34 /// // ... |
35 /// }, onError: (error, stackChain) { | 35 /// }, onError: (error, stackChain) { |
36 /// print("Caught error $error\n" | 36 /// print("Caught error $error\n" |
37 /// "$stackChain"); | 37 /// "$stackChain"); |
38 /// }); | 38 /// }); |
39 class Chain implements StackTrace { | 39 class Chain implements StackTrace { |
40 | |
41 /// The stack traces that make up this chain. | 40 /// The stack traces that make up this chain. |
42 /// | 41 /// |
43 /// Like the frames in a stack trace, the traces are ordered from most local | 42 /// 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 | 43 /// 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. | 44 /// raised, the second one is where that callback was scheduled, and so on. |
46 final List<Trace> traces; | 45 final List<Trace> traces; |
47 | 46 |
48 /// The [StackZoneSpecification] for the current zone. | 47 /// The [StackZoneSpecification] for the current zone. |
49 static StackZoneSpecification get _currentSpec => | 48 static StackZoneSpecification get _currentSpec => |
50 Zone.current[#stack_trace.stack_zone.spec]; | 49 Zone.current[#stack_trace.stack_zone.spec]; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 /// | 147 /// |
149 /// If [terse] is true, this will also fold together frames from the core | 148 /// If [terse] is true, this will also fold together frames from the core |
150 /// library or from this package, and simplify core library frames as in | 149 /// library or from this package, and simplify core library frames as in |
151 /// [Trace.terse]. | 150 /// [Trace.terse]. |
152 Chain foldFrames(bool predicate(Frame frame), {bool terse: false}) { | 151 Chain foldFrames(bool predicate(Frame frame), {bool terse: false}) { |
153 var foldedTraces = traces.map( | 152 var foldedTraces = traces.map( |
154 (trace) => trace.foldFrames(predicate, terse: terse)); | 153 (trace) => trace.foldFrames(predicate, terse: terse)); |
155 var nonEmptyTraces = foldedTraces.where((trace) { | 154 var nonEmptyTraces = foldedTraces.where((trace) { |
156 // Ignore traces that contain only folded frames. | 155 // Ignore traces that contain only folded frames. |
157 if (trace.frames.length > 1) return true; | 156 if (trace.frames.length > 1) return true; |
| 157 if (trace.frames.isEmpty) return false; |
158 | 158 |
159 // In terse mode, the trace may have removed an outer folded frame, | 159 // In terse mode, the trace may have removed an outer folded frame, |
160 // leaving a single non-folded frame. We can detect a folded frame because | 160 // leaving a single non-folded frame. We can detect a folded frame because |
161 // it has no line information. | 161 // it has no line information. |
162 if (!terse) return false; | 162 if (!terse) return false; |
163 return trace.frames.single.line != null; | 163 return trace.frames.single.line != null; |
164 }); | 164 }); |
165 | 165 |
166 // If all the traces contain only internal processing, preserve the last | 166 // If all the traces contain only internal processing, preserve the last |
167 // (top-most) one so that the chain isn't empty. | 167 // (top-most) one so that the chain isn't empty. |
(...skipping 19 matching lines...) Expand all Loading... |
187 | 187 |
188 // Don't call out to [Trace.toString] here because that doesn't ensure that | 188 // Don't call out to [Trace.toString] here because that doesn't ensure that |
189 // padding is consistent across all traces. | 189 // padding is consistent across all traces. |
190 return traces.map((trace) { | 190 return traces.map((trace) { |
191 return trace.frames.map((frame) { | 191 return trace.frames.map((frame) { |
192 return '${padRight(frame.location, longest)} ${frame.member}\n'; | 192 return '${padRight(frame.location, longest)} ${frame.member}\n'; |
193 }).join(); | 193 }).join(); |
194 }).join(chainGap); | 194 }).join(chainGap); |
195 } | 195 } |
196 } | 196 } |
OLD | NEW |