Bug 1245153 - Add error.wrap to wrap Error prototypes; r=automatedtester
Generally, Error prototypes that are not based on WebDriverError must
be wrapped so that they can be serialised across the AsyncMessageChannel.
MozReview-Commit-ID: EtkpEOBhrST
--- a/testing/marionette/error.js
+++ b/testing/marionette/error.js
@@ -69,16 +69,27 @@ error.isError = function(val) {
* Checks if obj is an object in the WebDriverError prototypal chain.
*/
error.isWebDriverError = function(obj) {
return error.isError(obj) &&
("name" in obj && ERRORS.indexOf(obj.name) >= 0);
};
/**
+ * Wraps an Error prototype in a WebDriverError. If the given error is
+ * already a WebDriverError, this is effectively a no-op.
+ */
+error.wrap = function(err) {
+ if (error.isWebDriverError(err)) {
+ return err;
+ }
+ return new WebDriverError(`${err.name}: ${err.message}`, err.stack);
+};
+
+/**
* Unhandled error reporter. Dumps the error and its stacktrace to console,
* and reports error to the Browser Console.
*/
error.report = function(err) {
let msg = `Marionette threw an error: ${error.stringify(err)}`;
dump(msg + "\n");
if (Cu.reportError) {
Cu.reportError(msg);
@@ -146,21 +157,22 @@ 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.
*/
-this.WebDriverError = function(msg) {
+this.WebDriverError = function(msg, stack = undefined) {
Error.call(this, msg);
this.name = "WebDriverError";
this.message = msg;
this.status = "webdriver error";
+ this.stack = stack;
};
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_error.js
+++ b/testing/marionette/test_error.js
@@ -59,16 +59,31 @@ add_test(function test_isWebDriverError(
notok(error.isWebDriverError(new URIError()));
ok(error.isWebDriverError(new WebDriverError()));
ok(error.isWebDriverError(new InvalidArgumentError()));
run_next_test();
});
+add_test(function test_wrap() {
+ equal(error.wrap(new WebDriverError()).name, "WebDriverError");
+ equal(error.wrap(new InvalidArgumentError()).name, "InvalidArgumentError");
+ equal(error.wrap(new Error()).name, "WebDriverError");
+ equal(error.wrap(new EvalError()).name, "WebDriverError");
+ equal(error.wrap(new InternalError()).name, "WebDriverError");
+ equal(error.wrap(new RangeError()).name, "WebDriverError");
+ equal(error.wrap(new ReferenceError()).name, "WebDriverError");
+ equal(error.wrap(new SyntaxError()).name, "WebDriverError");
+ equal(error.wrap(new TypeError()).name, "WebDriverError");
+ equal(error.wrap(new URIError()).name, "WebDriverError");
+
+ run_next_test();
+});
+
add_test(function test_stringify() {
equal("<unprintable error>", error.stringify());
equal("<unprintable error>", error.stringify("foo"));
equal("[object Object]", error.stringify({}));
equal("[object Object]\nfoo", error.stringify({stack: "foo"}));
equal("Error: foo", error.stringify(new Error("foo")).split("\n")[0]);
equal("WebDriverError: foo",
error.stringify(new WebDriverError("foo")).split("\n")[0]);