| 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 import 'dart:async'; | 5 import 'dart:async'; |
| 6 | 6 |
| 7 import 'chain.dart'; | 7 import 'chain.dart'; |
| 8 import 'lazy_trace.dart'; | 8 import 'lazy_trace.dart'; |
| 9 import 'trace.dart'; | 9 import 'trace.dart'; |
| 10 import 'utils.dart'; | 10 import 'utils.dart'; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 /// (converted to a [Trace] if necessary). If there is no chain associated | 85 /// (converted to a [Trace] if necessary). If there is no chain associated |
| 86 /// with [trace], this just returns a single-trace chain containing [trace]. | 86 /// with [trace], this just returns a single-trace chain containing [trace]. |
| 87 Chain chainFor(StackTrace trace) { | 87 Chain chainFor(StackTrace trace) { |
| 88 if (trace is Chain) return trace; | 88 if (trace is Chain) return trace; |
| 89 var previous = trace == null ? null : _chains[trace]; | 89 var previous = trace == null ? null : _chains[trace]; |
| 90 return new _Node(trace, previous).toChain(); | 90 return new _Node(trace, previous).toChain(); |
| 91 } | 91 } |
| 92 | 92 |
| 93 /// Tracks the current stack chain so it can be set to [_currentChain] when | 93 /// Tracks the current stack chain so it can be set to [_currentChain] when |
| 94 /// [f] is run. | 94 /// [f] is run. |
| 95 ZoneCallback _registerCallback( | 95 ZoneCallback<R> _registerCallback<R>( |
| 96 Zone self, ZoneDelegate parent, Zone zone, Function f) { | 96 Zone self, ZoneDelegate parent, Zone zone, R f()) { |
| 97 if (f == null || _disabled) return parent.registerCallback(zone, f); | 97 if (f == null || _disabled) return parent.registerCallback(zone, f); |
| 98 var node = _createNode(1); | 98 var node = _createNode(1); |
| 99 return parent.registerCallback(zone, () => _run(f, node)); | 99 return parent.registerCallback(zone, () => _run(f, node)); |
| 100 } | 100 } |
| 101 | 101 |
| 102 /// Tracks the current stack chain so it can be set to [_currentChain] when | 102 /// Tracks the current stack chain so it can be set to [_currentChain] when |
| 103 /// [f] is run. | 103 /// [f] is run. |
| 104 ZoneUnaryCallback _registerUnaryCallback( | 104 ZoneUnaryCallback<R, T> _registerUnaryCallback<R, T>( |
| 105 Zone self, ZoneDelegate parent, Zone zone, Function f) { | 105 Zone self, ZoneDelegate parent, Zone zone, R f(T arg)) { |
| 106 if (f == null || _disabled) return parent.registerUnaryCallback(zone, f); | 106 if (f == null || _disabled) return parent.registerUnaryCallback(zone, f); |
| 107 var node = _createNode(1); | 107 var node = _createNode(1); |
| 108 return parent.registerUnaryCallback(zone, (arg) { | 108 return parent.registerUnaryCallback(zone, (arg) { |
| 109 return _run(() => f(arg), node); | 109 return _run(() => f(arg), node); |
| 110 }); | 110 }); |
| 111 } | 111 } |
| 112 | 112 |
| 113 /// Tracks the current stack chain so it can be set to [_currentChain] when | 113 /// Tracks the current stack chain so it can be set to [_currentChain] when |
| 114 /// [f] is run. | 114 /// [f] is run. |
| 115 ZoneBinaryCallback _registerBinaryCallback( | 115 ZoneBinaryCallback<R, T1, T2> _registerBinaryCallback<R, T1, T2>( |
| 116 Zone self, ZoneDelegate parent, Zone zone, Function f) { | 116 Zone self, ZoneDelegate parent, Zone zone, Function f) { |
| 117 if (f == null || _disabled) return parent.registerBinaryCallback(zone, f); | 117 if (f == null || _disabled) return parent.registerBinaryCallback(zone, f); |
| 118 | 118 |
| 119 var node = _createNode(1); | 119 var node = _createNode(1); |
| 120 return parent.registerBinaryCallback(zone, (arg1, arg2) { | 120 return parent.registerBinaryCallback(zone, (arg1, arg2) { |
| 121 return _run(() => f(arg1, arg2), node); | 121 return _run(() => f(arg1, arg2), node); |
| 122 }); | 122 }); |
| 123 } | 123 } |
| 124 | 124 |
| 125 /// Looks up the chain associated with [stackTrace] and passes it either to | 125 /// Looks up the chain associated with [stackTrace] and passes it either to |
| 126 /// [_onError] or [parent]'s error handler. | 126 /// [_onError] or [parent]'s error handler. |
| 127 _handleUncaughtError( | 127 void _handleUncaughtError( |
| 128 Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) { | 128 Zone self, ZoneDelegate parent, Zone zone, error, StackTrace stackTrace) { |
| 129 if (_disabled) { | 129 if (_disabled) { |
| 130 return parent.handleUncaughtError(zone, error, stackTrace); | 130 parent.handleUncaughtError(zone, error, stackTrace); |
| 131 return; |
| 131 } | 132 } |
| 132 | 133 |
| 133 var stackChain = chainFor(stackTrace); | 134 var stackChain = chainFor(stackTrace); |
| 134 if (_onError == null) { | 135 if (_onError == null) { |
| 135 return parent.handleUncaughtError(zone, error, stackChain); | 136 parent.handleUncaughtError(zone, error, stackChain); |
| 137 return; |
| 136 } | 138 } |
| 137 | 139 |
| 138 // TODO(nweiz): Currently this copies a lot of logic from [runZoned]. Just | 140 // TODO(nweiz): Currently this copies a lot of logic from [runZoned]. Just |
| 139 // allow [runBinary] to throw instead once issue 18134 is fixed. | 141 // allow [runBinary] to throw instead once issue 18134 is fixed. |
| 140 try { | 142 try { |
| 141 return self.parent.runBinary(_onError, error, stackChain); | 143 self.parent.runBinary(_onError, error, stackChain); |
| 142 } catch (newError, newStackTrace) { | 144 } catch (newError, newStackTrace) { |
| 143 if (identical(newError, error)) { | 145 if (identical(newError, error)) { |
| 144 return parent.handleUncaughtError(zone, error, stackChain); | 146 parent.handleUncaughtError(zone, error, stackChain); |
| 145 } else { | 147 } else { |
| 146 return parent.handleUncaughtError(zone, newError, newStackTrace); | 148 parent.handleUncaughtError(zone, newError, newStackTrace); |
| 147 } | 149 } |
| 148 } | 150 } |
| 149 } | 151 } |
| 150 | 152 |
| 151 /// Attaches the current stack chain to [stackTrace], replacing it if | 153 /// Attaches the current stack chain to [stackTrace], replacing it if |
| 152 /// necessary. | 154 /// necessary. |
| 153 AsyncError _errorCallback(Zone self, ZoneDelegate parent, Zone zone, | 155 AsyncError _errorCallback(Zone self, ZoneDelegate parent, Zone zone, |
| 154 Object error, StackTrace stackTrace) { | 156 Object error, StackTrace stackTrace) { |
| 155 if (_disabled) return parent.errorCallback(zone, error, stackTrace); | 157 if (_disabled) return parent.errorCallback(zone, error, stackTrace); |
| 156 | 158 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 173 /// that many frames up instead. | 175 /// that many frames up instead. |
| 174 _Node _createNode([int level = 0]) => | 176 _Node _createNode([int level = 0]) => |
| 175 new _Node(_currentTrace(level + 1), _currentNode); | 177 new _Node(_currentTrace(level + 1), _currentNode); |
| 176 | 178 |
| 177 // TODO(nweiz): use a more robust way of detecting and tracking errors when | 179 // TODO(nweiz): use a more robust way of detecting and tracking errors when |
| 178 // issue 15105 is fixed. | 180 // issue 15105 is fixed. |
| 179 /// Runs [f] with [_currentNode] set to [node]. | 181 /// Runs [f] with [_currentNode] set to [node]. |
| 180 /// | 182 /// |
| 181 /// If [f] throws an error, this associates [node] with that error's stack | 183 /// If [f] throws an error, this associates [node] with that error's stack |
| 182 /// trace. | 184 /// trace. |
| 183 _run(Function f, _Node node) { | 185 T _run<T>(T f(), _Node node) { |
| 184 var previousNode = _currentNode; | 186 var previousNode = _currentNode; |
| 185 _currentNode = node; | 187 _currentNode = node; |
| 186 try { | 188 try { |
| 187 return f(); | 189 return f(); |
| 188 } catch (e, stackTrace) { | 190 } catch (e, stackTrace) { |
| 189 _chains[stackTrace] = node; | 191 _chains[stackTrace] = node; |
| 190 rethrow; | 192 rethrow; |
| 191 } finally { | 193 } finally { |
| 192 _currentNode = previousNode; | 194 _currentNode = previousNode; |
| 193 } | 195 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 var text = stackTrace.toString(); | 230 var text = stackTrace.toString(); |
| 229 var index = text.indexOf(vmChainGap); | 231 var index = text.indexOf(vmChainGap); |
| 230 if (index != -1) text = text.substring(0, index); | 232 if (index != -1) text = text.substring(0, index); |
| 231 | 233 |
| 232 var trace = new Trace.parse(text); | 234 var trace = new Trace.parse(text); |
| 233 // JS includes a frame for the call to StackTrace.current, but the VM | 235 // 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. | 236 // doesn't, so we skip an extra frame in a JS context. |
| 235 return new Trace(trace.frames.skip(level + (inJS ? 2 : 1)), original: text); | 237 return new Trace(trace.frames.skip(level + (inJS ? 2 : 1)), original: text); |
| 236 }); | 238 }); |
| 237 } | 239 } |
| OLD | NEW |