| Index: lib/src/frame.dart
|
| diff --git a/lib/src/frame.dart b/lib/src/frame.dart
|
| index a5fd6ae2df0554ceb4a7dba0ce0ef6733db1d9b5..072983a1b3c03ad4a63268fe529fa9eae4e0f267 100644
|
| --- a/lib/src/frame.dart
|
| +++ b/lib/src/frame.dart
|
| @@ -7,6 +7,7 @@ library frame;
|
| import 'package:path/path.dart' as path;
|
|
|
| import 'trace.dart';
|
| +import 'unparsed_frame.dart';
|
|
|
| // #1 Foo._bar (file:///home/nweiz/code/stuff.dart:42:21)
|
| // #1 Foo._bar (file:///home/nweiz/code/stuff.dart:42)
|
| @@ -126,7 +127,7 @@ class Frame {
|
| }
|
|
|
| /// Parses a string representation of a Dart VM stack frame.
|
| - factory Frame.parseVM(String frame) {
|
| + factory Frame.parseVM(String frame) => _catchFormatException(frame, () {
|
| // The VM sometimes folds multiple stack frames together and replaces them
|
| // with "...".
|
| if (frame == '...') {
|
| @@ -134,9 +135,7 @@ class Frame {
|
| }
|
|
|
| var match = _vmFrame.firstMatch(frame);
|
| - if (match == null) {
|
| - throw new FormatException("Couldn't parse VM stack trace line '$frame'.");
|
| - }
|
| + if (match == null) return new UnparsedFrame(frame);
|
|
|
| // Get the pieces out of the regexp match. Function, URI and line should
|
| // always be found. The column is optional.
|
| @@ -149,14 +148,12 @@ class Frame {
|
| var line = lineAndColumn.length > 1 ? int.parse(lineAndColumn[1]) : null;
|
| var column = lineAndColumn.length > 2 ? int.parse(lineAndColumn[2]) : null;
|
| return new Frame(uri, line, column, member);
|
| - }
|
| + });
|
|
|
| /// Parses a string representation of a Chrome/V8 stack frame.
|
| - factory Frame.parseV8(String frame) {
|
| + factory Frame.parseV8(String frame) => _catchFormatException(frame, () {
|
| var match = _v8Frame.firstMatch(frame);
|
| - if (match == null) {
|
| - throw new FormatException("Couldn't parse V8 stack trace line '$frame'.");
|
| - }
|
| + if (match == null) return new UnparsedFrame(frame);
|
|
|
| // v8 location strings can be arbitrarily-nested, since it adds a layer of
|
| // nesting for each eval performed on that line.
|
| @@ -172,10 +169,7 @@ class Frame {
|
| }
|
|
|
| var urlMatch = _v8UrlLocation.firstMatch(location);
|
| - if (urlMatch == null) {
|
| - throw new FormatException(
|
| - "Couldn't parse V8 stack trace line '$frame'.");
|
| - }
|
| + if (urlMatch == null) return new UnparsedFrame(frame);
|
|
|
| return new Frame(
|
| _uriOrPathToUri(urlMatch[1]),
|
| @@ -197,7 +191,7 @@ class Frame {
|
| // functions.
|
| return parseLocation(match[3], "<fn>");
|
| }
|
| - }
|
| + });
|
|
|
| /// Parses a string representation of a JavaScriptCore stack trace.
|
| factory Frame.parseJSCore(String frame) => new Frame.parseV8(frame);
|
| @@ -209,12 +203,9 @@ class Frame {
|
| factory Frame.parseIE(String frame) => new Frame.parseV8(frame);
|
|
|
| /// Parses a string representation of a Firefox stack frame.
|
| - factory Frame.parseFirefox(String frame) {
|
| + factory Frame.parseFirefox(String frame) => _catchFormatException(frame, () {
|
| var match = _firefoxSafariFrame.firstMatch(frame);
|
| - if (match == null) {
|
| - throw new FormatException(
|
| - "Couldn't parse Firefox/Safari stack trace line '$frame'.");
|
| - }
|
| + if (match == null) return new UnparsedFrame(frame);
|
|
|
| // Normally this is a URI, but in a jsshell trace it can be a path.
|
| var uri = _uriOrPathToUri(match[3]);
|
| @@ -237,7 +228,7 @@ class Frame {
|
| var column = match[5] == null || match[5] == '' ?
|
| null : int.parse(match[5]);
|
| return new Frame(uri, line, column, member);
|
| - }
|
| + });
|
|
|
| /// Parses a string representation of a Safari 6.0 stack frame.
|
| @Deprecated("Use Frame.parseSafari instead.")
|
| @@ -251,7 +242,7 @@ class Frame {
|
| factory Frame.parseSafari(String frame) => new Frame.parseFirefox(frame);
|
|
|
| /// Parses this package's string representation of a stack frame.
|
| - factory Frame.parseFriendly(String frame) {
|
| + factory Frame.parseFriendly(String frame) => _catchFormatException(frame, () {
|
| var match = _friendlyFrame.firstMatch(frame);
|
| if (match == null) {
|
| throw new FormatException(
|
| @@ -268,7 +259,7 @@ class Frame {
|
| var line = match[2] == null ? null : int.parse(match[2]);
|
| var column = match[3] == null ? null : int.parse(match[3]);
|
| return new Frame(uri, line, column, match[4]);
|
| - }
|
| + });
|
|
|
| /// A regular expression matching an absolute URI.
|
| static final _uriRegExp = new RegExp(r'^[a-zA-Z][-+.a-zA-Z\d]*://');
|
| @@ -294,6 +285,18 @@ class Frame {
|
| return Uri.parse(uriOrPath);
|
| }
|
|
|
| + /// Runs [body] and returns its result.
|
| + ///
|
| + /// If [body] throws a [FormatException], returns an [UnparsedFrame] with
|
| + /// [text] instead.
|
| + static Frame _catchFormatException(String text, Frame body()) {
|
| + try {
|
| + return body();
|
| + } on FormatException catch (_) {
|
| + return new UnparsedFrame(text);
|
| + }
|
| + }
|
| +
|
| Frame(this.uri, this.line, this.column, this.member);
|
|
|
| String toString() => '$location in $member';
|
|
|