Bug 1507125 - Protocol Front should throw when called after destroy;r=ochameau
authorJulian Descottes <jdescottes@mozilla.com>
Thu, 29 Nov 2018 10:00:06 +0000
changeset 448720 dcec04522fb6d455270c8fe5059660e83574712c
parent 448719 0f93bf2d53ebd04b56f2cc6fa66c9028b7e08db3
child 448721 3e5ea9da2cbbb0e9ac5d27a277f921ca9d470c85
push id73975
push userjdescottes@mozilla.com
push dateThu, 29 Nov 2018 10:06:46 +0000
treeherderautoland@dcec04522fb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersochameau
bugs1507125
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1507125 - Protocol Front should throw when called after destroy;r=ochameau Depends on D13137. Differential Revision: https://phabricator.services.mozilla.com/D13138
devtools/server/tests/unit/test_front_destroy.js
devtools/server/tests/unit/xpcshell.ini
devtools/shared/protocol.js
new file mode 100644
--- /dev/null
+++ b/devtools/server/tests/unit/test_front_destroy.js
@@ -0,0 +1,31 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * Test that fronts throw errors if they are called after being destroyed.
+ */
+
+"use strict";
+
+add_task(async function test() {
+  DebuggerServer.init();
+  DebuggerServer.registerAllActors();
+
+  info("Create and connect the DebuggerClient");
+  const transport = DebuggerServer.connectPipe();
+  const client = new DebuggerClient(transport);
+  await client.connect();
+
+  info("Get the device front and check calling getDescription() on it");
+  const front = await client.mainRoot.getFront("device");
+  const description = await front.getDescription();
+  ok(!!description, "Check that the getDescription() method returns a valid response.");
+
+  info("Destroy the device front and try calling getDescription again");
+  front.destroy();
+  Assert.throws(() => front.getDescription(),
+    /Can not send request because front 'device' is already destroyed\./,
+    "Check device front throws when getDescription() is called after destroy()");
+
+  await client.close();
+});
--- a/devtools/server/tests/unit/xpcshell.ini
+++ b/devtools/server/tests/unit/xpcshell.ini
@@ -78,16 +78,17 @@ skip-if = (verify && !debug && (os == 'w
 [test_threadlifetime-02.js]
 [test_threadlifetime-03.js]
 [test_threadlifetime-04.js]
 [test_threadlifetime-05.js]
 [test_threadlifetime-06.js]
 [test_functiongrips-01.js]
 [test_frameclient-01.js]
 [test_frameclient-02.js]
+[test_front_destroy.js]
 [test_nativewrappers.js]
 [test_nodelistactor.js]
 [test_eval-01.js]
 [test_eval-02.js]
 [test_eval-03.js]
 [test_eval-04.js]
 [test_eval-05.js]
 [test_format_command.js]
--- a/devtools/shared/protocol.js
+++ b/devtools/shared/protocol.js
@@ -1517,16 +1517,23 @@ var generateRequestMethods = function(ac
       // If the user doesn't need the impl don't generate it.
       if (!custom.impl) {
         return;
       }
       name = custom.impl;
     }
 
     frontProto[name] = function(...args) {
+      // If this.actorID are not available, the request will not be able to complete.
+      // The front was probably destroyed earlier.
+      if (!this.actorID) {
+        throw new Error(
+          `Can not send request because front '${this.typeName}' is already destroyed.`);
+      }
+
       let packet;
       try {
         packet = spec.request.write(args, this);
       } catch (ex) {
         console.error("Error writing request: " + name);
         throw ex;
       }
       if (spec.oneway) {