Bug 1326534 - Preserve stacks when passing error protos to WebDriverError; r?automatedtester draft
authorAndreas Tolfsen <ato@mozilla.com>
Fri, 30 Dec 2016 11:26:30 +0000
changeset 457104 a2cb1121cf3dbc430d1bc9c83856cc5ac090958a
parent 457103 7936520f03f7d8c69c352ae40ab04c54001a2957
child 457105 64ac13861b524c0d85a9a384f663df899a8d9548
push id40670
push userbmo:ato@mozilla.com
push dateFri, 06 Jan 2017 18:52:13 +0000
reviewersautomatedtester
bugs1326534
milestone53.0a1
Bug 1326534 - Preserve stacks when passing error protos to WebDriverError; r?automatedtester The `stack` argument to `WebDriverError` has never been in use. Following the API of the `Error` prototype, this changes its constructor to take one argument which can either be a string of an `Error`. When internal errors are thrown in Marionette, they are usually wrapped in `WebDriverError` but we currently lose track of its stack. This preserves the wrapped error's stacktrace by setting the `stack` property. Practice have found that they are very useful to return to the client, as they are currently only printed to stdout. MozReview-Commit-ID: 9sTdP4TntIc
testing/marionette/error.js
testing/marionette/test_message.js
--- a/testing/marionette/error.js
+++ b/testing/marionette/error.js
@@ -200,24 +200,32 @@ error.fromJson = function (json) {
   }
   return err;
 };
 
 /**
  * WebDriverError is the prototypal parent of all WebDriver errors.
  * It should not be used directly, as it does not correspond to a real
  * error in the specification.
+ *
+ * @param {(string|Error)=} err
+ *     Optional string describing error situation or Error instance
+ *     to propagate.
  */
-this.WebDriverError = function (msg, stack = undefined) {
-  Error.call(this, msg);
+this.WebDriverError = function (err) {
+  Error.call(this, err);
   this.name = "WebDriverError";
-  this.message = msg;
-  this.stack = stack;
   this.status = "webdriver error";
-  this.stack = stack;
+
+  if (error.isError(err)) {
+    this.message = err.message;
+    this.stack = err.stack;
+  } else {
+    this.message = err;
+  }
 };
 WebDriverError.prototype = Object.create(Error.prototype);
 
 this.ElementNotAccessibleError = function (msg) {
   WebDriverError.call(this, msg);
   this.name = "ElementNotAccessibleError";
   this.status = "element not accessible";
 };
--- a/testing/marionette/test_message.js
+++ b/testing/marionette/test_message.js
@@ -138,17 +138,17 @@ add_test(function test_Response_send() {
   equal(true, fired);
 
   run_next_test();
 });
 
 add_test(function test_Response_sendError() {
   let err = new WebDriverError();
   let resp = new Response(42, r => {
-    deepEqual(error.toJson(err), r.error);
+    equal(error.toJson(err).error, r.error.error);
     equal(null, r.body);
     equal(false, r.sent);
   });
 
   resp.sendError(err);
   equal(true, resp.sent);
   Assert.throws(() => resp.send(), /already been sent/);