44
55import 'dart:async' ;
66
7- import 'trace.dart' ;
87import 'chain.dart' ;
8+ import 'lazy_trace.dart' ;
9+ import 'trace.dart' ;
10+ import 'utils.dart' ;
911
1012/// A function that handles errors in the zone wrapped by [Chain.capture] .
1113typedef void _ChainHandler (error, Chain chain);
@@ -170,7 +172,7 @@ class StackZoneSpecification {
170172 /// [_createNode] is called. If [level] is passed, the first trace will start
171173 /// that many frames up instead.
172174 _Node _createNode ([int level= 0 ]) =>
173- new _Node (new Trace . current (level + 1 ), _currentNode);
175+ new _Node (_currentTrace (level + 1 ), _currentNode);
174176
175177 // TODO(nweiz): use a more robust way of detecting and tracking errors when
176178 // issue 15105 is fixed.
@@ -201,7 +203,7 @@ class _Node {
201203 final _Node previous;
202204
203205 _Node (StackTrace trace, [this .previous])
204- : trace = trace == null ? new Trace . current () : new Trace .from (trace);
206+ : trace = trace == null ? _currentTrace () : new Trace .from (trace);
205207
206208 /// Converts this to a [Chain] .
207209 Chain toChain () {
@@ -214,3 +216,22 @@ class _Node {
214216 return new Chain (nodes);
215217 }
216218}
219+
220+ /// Like [new Trace.current] , but if the current stack trace has VM chaining
221+ /// enabled, this only returns the innermost sub-trace.
222+ Trace _currentTrace ([int level]) {
223+ level ?? = 0 ;
224+ var stackTrace = StackTrace .current;
225+ return new LazyTrace (() {
226+ // Ignore the VM's stack chains when we generate our own. Otherwise we'll
227+ // end up with duplicate frames all over the place.
228+ var text = stackTrace.toString ();
229+ var index = text.indexOf (vmChainGap);
230+ if (index != - 1 ) text = text.substring (0 , index);
231+
232+ var trace = new Trace .parse (text);
233+ // JS includes a frame for the call to StackTrace.current, but the VM
234+ // doesn't, so we skip an extra frame in a JS context.
235+ return new Trace (trace.frames.skip (level + (inJS ? 2 : 1 )));
236+ });
237+ }
0 commit comments