Merge pull request #27 from dart-lang/devoncarew_st
add a library method to clean stack traces
diff --git a/changelog.md b/changelog.md
index 0009277..119692a 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,9 @@
# Changelog
+## 0.0.4
+
+- Moved `sanitizeStacktrace` into the main library
+
## 0.0.3
- Replaced optional positional arguments with named arguments
@@ -9,7 +13,7 @@
## 0.0.2
- Fixed a bug in `analytics.sendTiming()`
-
+
## 0.0.1
- Initial version, created by Stagehand
diff --git a/lib/src/usage_impl.dart b/lib/src/usage_impl.dart
index 7a24819..6ee4e43 100644
--- a/lib/src/usage_impl.dart
+++ b/lib/src/usage_impl.dart
@@ -13,9 +13,6 @@
final int _MAX_EXCEPTION_LENGTH = 100;
-// Matches file:/, non-ws, /, non-ws, .dart
-final RegExp _pathRegex = new RegExp(r'file:/\S+/(\S+\.dart)');
-
String postEncode(Map<String, dynamic> map) {
// &foo=bar
return map.keys.map((key) {
@@ -25,30 +22,6 @@
}
/**
- * Santitize a string potentially containing file paths. This will remove all
- * but the last file name in order to remove any PII that may be contained in
- * the full file path. For example, this will shorten:
- *
- * file:///Users/foobar/tmp/error.dart
- *
- * to
- *
- * error.dart
- */
-String sanitizeFilePaths(String stackTrace) {
- Iterable<Match> iter = _pathRegex.allMatches(stackTrace);
- iter = iter.toList().reversed;
-
- for (Match match in iter) {
- String replacement = match.group(1);
- stackTrace = stackTrace.substring(0, match.start)
- + replacement + stackTrace.substring(match.end);
- }
-
- return stackTrace;
-}
-
-/**
* A throttling algorithim. This models the throttling after a bucket with
* water dripping into it at the rate of 1 drop per second. If the bucket has
* water when an operation is requested, 1 drop of water is removed and the
diff --git a/lib/usage.dart b/lib/usage.dart
index 9ddcb9e..9496095 100644
--- a/lib/usage.dart
+++ b/lib/usage.dart
@@ -26,6 +26,9 @@
import 'dart:async';
+// Matches file:/, non-ws, /, non-ws, .dart
+final RegExp _pathRegex = new RegExp(r'file:/\S+/(\S+\.dart)');
+
/**
* An interface to a Google Analytics session. [AnalyticsHtml] and [AnalyticsIO]
* are concrete implementations of this interface. [AnalyticsMock] can be used
@@ -144,3 +147,36 @@
return new Future.value();
}
}
+
+/**
+ * Santitize a stacktrace. This will shorten file paths in order to remove any
+ * PII that may be contained in the full file path. For example, this will
+ * shorten `file:///Users/foobar/tmp/error.dart` to `error.dart`.
+ *
+ * If [shorten] is `true`, this method will also attempt to compress the text
+ * of the stacktrace. GA has a 100 char limit on the text that can be sent for
+ * an exception. This will try and make those first 100 chars contain
+ * information useful to debugging the issue.
+ */
+String sanitizeStacktrace(dynamic st, {bool shorten: true}) {
+ String str = '${st}';
+
+ Iterable<Match> iter = _pathRegex.allMatches(str);
+ iter = iter.toList().reversed;
+
+ for (Match match in iter) {
+ String replacement = match.group(1);
+ str = str.substring(0, match.start)
+ + replacement + str.substring(match.end);
+ }
+
+ if (shorten) {
+ // Shorten the stacktrace up a bit.
+ str = str
+ .replaceAll('(package:', '(')
+ .replaceAll('(dart:', '(')
+ .replaceAll(new RegExp(r'\s+'), ' ');
+ }
+
+ return str;
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index 6ab1556..21e61f2 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
name: usage
-version: 0.0.4-dev
+version: 0.0.4
description: A Google Analytics wrapper for both command-line and web apps.
homepage: https://github.com/dart-lang/usage
author: Dart Team <misc@dartlang.org>
diff --git a/readme.md b/readme.md
index 496ff0b..520c4b9 100644
--- a/readme.md
+++ b/readme.md
@@ -3,7 +3,7 @@
`usage` is a wrapper around Google Analytics for both command-line apps and web
apps.
-[![Build Status](https://travis-ci.org/dart-lang/usage.svg)](https://travis-ci.org/dart-lang/usage)
+[![Build Status](https://travis-ci.org/dart-lang/usage.svg)](https://travis-ci.org/dart-lang/usage)
[![Coverage Status](https://img.shields.io/coveralls/dart-lang/usage.svg)](https://coveralls.io/r/dart-lang/usage?branch=master)
## For web apps
diff --git a/test/usage_impl_test.dart b/test/usage_impl_test.dart
index 80b8690..6622825 100644
--- a/test/usage_impl_test.dart
+++ b/test/usage_impl_test.dart
@@ -54,21 +54,6 @@
});
});
- group('sanitizeFilePaths', () {
- test('replace file', () {
- expect(sanitizeFilePaths(
- '(file:///Users/foo/tmp/error.dart:3:13)'),
- '(error.dart:3:13)');
- });
-
- test('replace files', () {
- expect(sanitizeFilePaths(
- 'foo (file:///Users/foo/tmp/error.dart:3:13)\n'
- 'bar (file:///Users/foo/tmp/error.dart:3:13)'),
- 'foo (error.dart:3:13)\nbar (error.dart:3:13)');
- });
- });
-
group('postEncode', () {
test('simple', () {
Map map = {'foo': 'bar', 'baz': 'qux norf'};
diff --git a/test/usage_test.dart b/test/usage_test.dart
index 5edfa45..e92caf3 100644
--- a/test/usage_test.dart
+++ b/test/usage_test.dart
@@ -19,4 +19,41 @@
mock.setSessionValue('val', 'ue');
});
});
+
+ group('sanitizeStacktrace', () {
+ test('replace file', () {
+ expect(sanitizeStacktrace(
+ '(file:///Users/foo/tmp/error.dart:3:13)',
+ shorten: false),
+ '(error.dart:3:13)');
+ });
+
+ test('replace files', () {
+ expect(sanitizeStacktrace(
+ 'foo (file:///Users/foo/tmp/error.dart:3:13)\n'
+ 'bar (file:///Users/foo/tmp/error.dart:3:13)',
+ shorten: false),
+ 'foo (error.dart:3:13)\nbar (error.dart:3:13)');
+ });
+
+ test('shorten 1', () {
+ expect(sanitizeStacktrace(
+ '(file:///Users/foo/tmp/error.dart:3:13)'),
+ '(error.dart:3:13)');
+ });
+
+ test('shorten 2', () {
+ expect(sanitizeStacktrace(
+ 'foo (file:///Users/foo/tmp/error.dart:3:13)\n'
+ 'bar (file:///Users/foo/tmp/error.dart:3:13)'),
+ 'foo (error.dart:3:13) bar (error.dart:3:13)');
+ });
+
+ test('shorten 3', () {
+ expect(sanitizeStacktrace(
+ 'foo (package:foo/foo.dart:3:13)\n'
+ 'bar (dart:async/schedule_microtask.dart:41)'),
+ 'foo (foo/foo.dart:3:13) bar (async/schedule_microtask.dart:41)');
+ });
+ });
}