stack_trace
stack_trace copied to clipboard
Trace.parse() does not correctly parse standard stacks in stderr from the Dart VM
If I run:
main() {
throw 'test';
}
I get the output:
Unhandled exception:
test
#0 main (file:///Users/danny/Desktop/dart_sample/bin/trace.dart:2:3)
#1 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#2 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
If I feed this into Trace.parse
, it doesn't appear to parse correctly (it goes into Trace.parseFriendly
, and that doesn't seem to handle this format):
import 'package:stack_trace/stack_trace.dart';
main() {
final stderrOutput = '''
Unhandled exception:
test
#0 main (file:///Users/danny/Desktop/dart_sample/bin/trace.dart:2:3)
#1 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#2 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)
'''
.trim();
final trace = Trace.parse(stderrOutput);
for (final frame in trace.frames) {
print('${frame.uri} ${frame.line}:${frame.column}');
}
}
Outputs:
file:///Users/danny/Desktop/dart_sample null:null
file:///Users/danny/Desktop/dart_sample null:null
file:///Users/danny/Desktop/dart_sample null:null
The URIs and line/col don't seem to have been parsed correctly. Calling Trace.parseVm()
works correctly, but I don't know for certain that the stack will always be from a VM and thought Trace.parse
should handle this.
Turns out this is triggered by the line Unhandled exception:
which apparently looks like a friendly trace line.
I'm not sure if that's intended or not. I was hoping that would just become an unparsed frame. I'm only getting the full stderr
output so don't know where the stack starts/ends and was hoping any non-frame parts would become unparsed frames.
I can probably work around this by trying to detect the platform and calling the relevant constructor, though perhaps there's a more restrictive way friendly constructors could be detected (or, there could be a boolean flag to opt-out of the friendly parsing (or allowing it to also handle these frames)?
This is working as intended. This library parses the StackTrace.toString
output. Example:
class C {
void f() {
g();
}
void g() {
throw 'hi';
}
}
void main() {
try {
C().f();
} catch (e, st) {
final trace = Trace.parse(st.toString()); // works
print(trace);
}
}
In SDK backends (VM, dart2js, dart2wasm) the errors caught at the top-level are reported as: the error object, stack trace, and maybe some lines before/after/in-between. The library does not try to parse these formats.