Detect when isolate reload is barred and inform the user (#5602)

diff --git a/packages/flutter_tools/lib/src/hot.dart b/packages/flutter_tools/lib/src/hot.dart
index fa98e83..9e9dc70 100644
--- a/packages/flutter_tools/lib/src/hot.dart
+++ b/packages/flutter_tools/lib/src/hot.dart
@@ -445,9 +445,18 @@
       } else {
         flutterUsage.sendEvent('hot', 'reload');
       }
-    } catch (errorMessage, st) {
+    } catch (error, st) {
+      int errorCode = error['code'];
+      if (errorCode == Isolate.kIsolateReloadBarred) {
+        printError('Unable to hot reload app due to an unrecoverable error in '
+                   'the source code. Please address the error and then '
+                   'Use "R" to restart the app.');
+        flutterUsage.sendEvent('hot', 'reload-barred');
+        return false;
+      }
+      String errorMessage = error['message'];
       reloadStatus.stop(showElapsedTime: true);
-      printError('Hot reload failed:\n$errorMessage\n$st');
+      printError('Hot reload failed:\ncode = $errorCode\nmessage = $errorMessage\n$st');
       return false;
     }
     await _evictDirtyAssets();
diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart
index cc021ed..153c002 100644
--- a/packages/flutter_tools/lib/src/vmservice.dart
+++ b/packages/flutter_tools/lib/src/vmservice.dart
@@ -749,12 +749,18 @@
     _upgradeCollection(map, this);
   }
 
+  static final int kIsolateReloadBarred = 1005;
+
   Future<Map<String, dynamic>> reloadSources() async {
     try {
       Map<String, dynamic> response = await invokeRpcRaw('_reloadSources');
       return response;
-    } catch (e) {
-      return new Future<Map<String, dynamic>>.error(e.data['details']);
+    } on rpc.RpcException catch(e) {
+      return new Future<Map<String, dynamic>>.error(<String, dynamic>{
+        'code': e.code,
+        'message': e.message,
+        'data': e.data,
+      });
     }
   }