add better error handling when stdin gives an error instead of EOF
diff --git a/CHANGELOG.md b/CHANGELOG.md
index dd62957..d81018c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.2
+
+* Add better handling for the case where stdin gives an error instead of an EOF. 
+
 ## 0.1.1
 
 * Export `AsyncMessageGrouper` and `SyncMessageGrouper` as part of the testing
diff --git a/lib/src/async_message_grouper.dart b/lib/src/async_message_grouper.dart
index 448f51e..93caf49 100644
--- a/lib/src/async_message_grouper.dart
+++ b/lib/src/async_message_grouper.dart
@@ -27,19 +27,26 @@
 
   /// Returns the next full message that is received, or null if none are left.
   Future<List<int>> get next async {
-    List<int> message;
-    while (
-        message == null && (_buffer.isNotEmpty || await _inputQueue.hasNext)) {
-      if (_buffer.isEmpty) _buffer.addAll(await _inputQueue.next);
-      var nextByte = _buffer.removeFirst();
-      if (nextByte == -1) return null;
-      message = _state.handleInput(nextByte);
+    try {
+      List<int> message;
+      while (message == null &&
+          (_buffer.isNotEmpty || await _inputQueue.hasNext)) {
+        if (_buffer.isEmpty) _buffer.addAll(await _inputQueue.next);
+        var nextByte = _buffer.removeFirst();
+        if (nextByte == -1) return null;
+        message = _state.handleInput(nextByte);
+      }
+
+      // If there is nothing left in the queue then cancel the subscription.
+      if (message == null) _inputQueue.cancel();
+
+      return message;
+    } catch (e) {
+      // It appears we sometimes get an exception instead of -1 as expected when
+      // stdin closes, this handles that in the same way (returning a null
+      // message)
+      return null;
     }
-
-    // If there is nothing left in the queue then cancel the subscription.
-    if (message == null) _inputQueue.cancel();
-
-    return message;
   }
 
   /// Stop listening to the stream for further updates.
diff --git a/lib/src/sync_message_grouper.dart b/lib/src/sync_message_grouper.dart
index 50d5dca..20a1139 100644
--- a/lib/src/sync_message_grouper.dart
+++ b/lib/src/sync_message_grouper.dart
@@ -18,12 +18,19 @@
   ///
   /// Returns null at end of file.
   List<int> get next {
-    List<int> message;
-    while (message == null) {
-      var nextByte = _stdin.readByteSync();
-      if (nextByte == -1) return null;
-      message = _state.handleInput(nextByte);
+    try {
+      List<int> message;
+      while (message == null) {
+        var nextByte = _stdin.readByteSync();
+        if (nextByte == -1) return null;
+        message = _state.handleInput(nextByte);
+      }
+      return message;
+    } catch (e) {
+      // It appears we sometimes get an exception instead of -1 as expected when
+      // stdin closes, this handles that in the same way (returning a null
+      // message)
+      return null;
     }
-    return message;
   }
 }
diff --git a/lib/testing.dart b/lib/testing.dart
index ecc3142..882097f 100644
--- a/lib/testing.dart
+++ b/lib/testing.dart
@@ -51,6 +51,7 @@
 class TestStdinAsync implements TestStdin {
   /// Controls the stream for async delivery of bytes.
   final StreamController _controller = new StreamController();
+  StreamController get controller => _controller;
 
   /// Adds all the [bytes] to this stream.
   void addInputBytes(List<int> bytes) {
diff --git a/pubspec.yaml b/pubspec.yaml
index 241861f..e7e589e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: bazel_worker
-version: 0.1.1
+version: 0.1.2
 description: Tools for creating a bazel persistent worker.
 author: Dart Team <misc@dartlang.org>
 homepage: https://github.com/dart-lang/bazel_worker
diff --git a/test/message_grouper_test.dart b/test/message_grouper_test.dart
index 8a975fb..39dcb9e 100644
--- a/test/message_grouper_test.dart
+++ b/test/message_grouper_test.dart
@@ -137,4 +137,15 @@
       [30, 40]
     ]);
   });
+
+  test('Handles the case when stdin gives an error instead of EOF', () async {
+    if (stdinStream is TestStdinSync) {
+      // Reading will now cause an error as pendingBytes is empty.
+      (stdinStream as TestStdinSync).pendingBytes.clear();
+      expect(messageGrouper.next, isNull);
+    } else if (stdinStream is TestStdinAsync) {
+      (stdinStream as TestStdinAsync).controller.addError('Error!');
+      expect(await messageGrouper.next, isNull);
+    }
+  });
 }
diff --git a/test/worker_loop_test.dart b/test/worker_loop_test.dart
index 1c27d5d..ac4dd11 100644
--- a/test/worker_loop_test.dart
+++ b/test/worker_loop_test.dart
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:async';
 import 'dart:io';
 
 import 'package:test/test.dart';
@@ -35,7 +36,7 @@
     TestWorkerLoop workerLoopFactory(/*=T*/ connection)) {
   TestStdin stdinStream;
   TestStdoutStream stdoutStream;
-  var /*=T*/ connection;
+  var/*=T*/ connection;
   TestWorkerLoop workerLoop;
 
   setUp(() {
@@ -86,4 +87,17 @@
     stdinStream.close();
     await workerLoop.run();
   });
+
+  test('Stops if stdin gives an error instead of EOF', () async {
+    if (stdinStream is TestStdinSync) {
+      // Reading will now cause an error as pendingBytes is empty.
+      (stdinStream as TestStdinSync).pendingBytes.clear();
+      await workerLoop.run();
+    } else if (stdinStream is TestStdinAsync) {
+      var done = new Completer();
+      workerLoop.run().then((_) => done.complete(null));
+      (stdinStream as TestStdinAsync).controller.addError('Error!!');
+      await done.future;
+    }
+  });
 }