Fixes to hotRestart (#922)

- Ensure we only return from a `hotRestart` after the corresponding `isolateStart` event
- Don't fail if the `hotRestart` falls back to a full reload
diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md
index b22561c..c6888bc 100644
--- a/dwds/CHANGELOG.md
+++ b/dwds/CHANGELOG.md
@@ -1,3 +1,9 @@
+## 2.0.1
+
+- Fix an issue where we would return prematurely during a `hotRestart`.
+- Fix an issue where we would incorrectly fail if a `hotRestart` had to
+  fall back to a full reload.
+
 ## 2.0.0
 
 - Depend on the latest `package:vm_service` version `3.0.0+1`.
diff --git a/dwds/lib/src/dwds_vm_client.dart b/dwds/lib/src/dwds_vm_client.dart
index 9eabb17..e7de226 100644
--- a/dwds/lib/src/dwds_vm_client.dart
+++ b/dwds/lib/src/dwds_vm_client.dart
@@ -7,6 +7,7 @@
 
 import 'package:logging/logging.dart';
 import 'package:vm_service/vm_service.dart';
+import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
 
 import 'services/chrome_proxy_service.dart' show ChromeProxyService;
 import 'services/debug_service.dart';
@@ -54,24 +55,32 @@
 
     client.registerServiceCallback('hotRestart', (request) async {
       await _disableBreakpointsAndResume(client, chromeProxyService);
-      var response = await chromeProxyService.remoteDebugger
-          .sendCommand('Runtime.evaluate', params: {
-        'expression': r'$dartHotRestart();',
-        'awaitPromise': true,
-        'contextId': await chromeProxyService.executionContext.id,
-      });
-      var exceptionDetails = response.result['exceptionDetails'];
-      if (exceptionDetails != null) {
-        return {
-          'error': {
-            'code': -32603,
-            'message': exceptionDetails['exception']['description'],
-            'data': exceptionDetails,
-          }
-        };
-      } else {
-        return {'result': Success().toJson()};
+      var context = await chromeProxyService.executionContext.id;
+      try {
+        await chromeProxyService.remoteDebugger
+            .sendCommand('Runtime.evaluate', params: {
+          'expression': r'$dartHotRestart();',
+          'awaitPromise': true,
+          'contextId': context,
+        });
+      } on WipError catch (exception) {
+        var code = exception.error['code'];
+        // This corresponds to `Execution context was destroyed` which can
+        // occur during a hot restart that must fall back to a full reload.
+        if (code != -32000) {
+          return {
+            'error': {
+              'code': exception.error['code'],
+              'message': exception.error['message'],
+              'data': exception,
+            }
+          };
+        }
       }
+      // Only return success after the isolate has fully started.
+      var stream = client.onEvent('Isolate');
+      await stream.firstWhere((event) => event.kind == EventKind.kIsolateStart);
+      return {'result': Success().toJson()};
     });
     await client.registerService('hotRestart', 'DWDS fullReload');
 
diff --git a/dwds/lib/src/version.dart b/dwds/lib/src/version.dart
index 0e58df3..6884ff8 100644
--- a/dwds/lib/src/version.dart
+++ b/dwds/lib/src/version.dart
@@ -1,2 +1,2 @@
 // Generated code. Do not modify.
-const packageVersion = '2.0.0';
+const packageVersion = '2.0.1';
diff --git a/dwds/pubspec.yaml b/dwds/pubspec.yaml
index f3fa147..818e478 100644
--- a/dwds/pubspec.yaml
+++ b/dwds/pubspec.yaml
@@ -1,5 +1,5 @@
 name: dwds
-version: 2.0.0
+version: 2.0.1
 homepage: https://github.com/dart-lang/webdev/tree/master/dwds
 description: >-
   A service that proxies between the Chrome debug protocol and the Dart VM