Fix a crash in Chain.terse and Chain.foldFrames.

These methods didn't gracefully handle a chain with an empty frame,
which comes up occasionally in practice.

Closes #9

R=rnystrom@google.com

Review URL: https://codereview.chromium.org//1492323004 .
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 624a934..dace263 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.5.1
+
+* Fix a crash in `Chain.foldFrames()` and `Chain.terse` when one of the chain's
+  traces has no frames.
+
 ## 1.5.0
 
 * `new Chain.parse()` now parses all the stack trace formats supported by `new
diff --git a/lib/src/chain.dart b/lib/src/chain.dart
index 2e07d4b..2e63ef0 100644
--- a/lib/src/chain.dart
+++ b/lib/src/chain.dart
@@ -37,7 +37,6 @@
 ///             "$stackChain");
 ///     });
 class Chain implements StackTrace {
-
   /// The stack traces that make up this chain.
   ///
   /// Like the frames in a stack trace, the traces are ordered from most local
@@ -155,6 +154,7 @@
     var nonEmptyTraces = foldedTraces.where((trace) {
       // Ignore traces that contain only folded frames.
       if (trace.frames.length > 1) return true;
+      if (trace.frames.isEmpty) return false;
 
       // In terse mode, the trace may have removed an outer folded frame,
       // leaving a single non-folded frame. We can detect a folded frame because
diff --git a/pubspec.yaml b/pubspec.yaml
index 932f648..16b2a1f 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -7,7 +7,7 @@
 #
 # When the major version is upgraded, you *must* update that version constraint
 # in pub to stay in sync with this.
-version: 1.5.0
+version: 1.5.1
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://github.com/dart-lang/stack_trace
 description: >
diff --git a/test/chain/chain_test.dart b/test/chain/chain_test.dart
index 0eb3f00..cddb4a6 100644
--- a/test/chain/chain_test.dart
+++ b/test/chain/chain_test.dart
@@ -109,6 +109,20 @@
 
       expect(chain.terse.toString(), equals('dart:core  E.f\n'));
     });
+
+    // Regression test for #9
+    test("doesn't crash on empty traces", () {
+      var chain = new Chain([
+        new Trace.parse('user/code.dart 10:11  Bang.qux'),
+        new Trace([]),
+        new Trace.parse('user/code.dart 10:11  Bang.qux')
+      ]);
+
+      expect(chain.terse.toString(), equals(
+          '$userSlashCode 10:11  Bang.qux\n'
+          '===== asynchronous gap ===========================\n'
+          '$userSlashCode 10:11  Bang.qux\n'));
+    });
   });
 
   group('Chain.foldFrames', () {