Skip to content

Commit

Permalink
Bug 945729: Replace error number codes with strings
Browse files Browse the repository at this point in the history
Brings Marionette closer to compliance with the W3C WebDriver standard
which prescribes that errors should be identified by a string rather
than a magic number.

r=dburns
  • Loading branch information
andreastt committed Apr 8, 2015
1 parent 8ced084 commit 40edcdc
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 50 deletions.
6 changes: 3 additions & 3 deletions testing/marionette/command.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ this.Response = function(cmdId, okHandler, respHandler, msg, sanitizer) {

this.data = new Map([
["sessionId", msg.sessionId ? msg.sessionId : null],
["status", msg.status ? msg.status : 0 /* success */],
["status", msg.status ? msg.status : "success"],
["value", msg.value ? msg.value : undefined],
]);
};
Expand Down Expand Up @@ -93,10 +93,10 @@ Response.prototype.send = function() {
/**
* @param {(Error|Object)} err
* The error to send, either an instance of the Error prototype,
* or an object with the properties "message", "code", and "stack".
* or an object with the properties "message", "status", and "stack".
*/
Response.prototype.sendError = function(err) {
this.status = "code" in err ? err.code : new UnknownError().code;
this.status = "status" in err ? err.status : new UnknownError().status;
this.value = error.toJSON(err);
this.send();

Expand Down
2 changes: 1 addition & 1 deletion testing/marionette/dispatcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Dispatcher.prototype.quitApplication = function(msg) {
if (this.driver.appName != "Firefox") {
this.sendError({
"message": "In app initiated quit only supported on Firefox",
"status": 500
"status": "webdriver error",
}, id);
return;
}
Expand Down
44 changes: 5 additions & 39 deletions testing/marionette/error.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,26 +59,14 @@ error.toJSON = function(err) {
return {
message: err.message,
stacktrace: err.stack || null,
status: err.code
status: err.status
};
};

/**
* Determines if the given status code is successful.
* Determines if the given status is successful.
*/
error.isSuccess = code => code === 0;

/**
* Old-style errors are objects that has all of the properties
* "message", "code", and "stack".
*
* When listener.js starts forwarding real errors by CPOW
* we can remove this.
*/
let isOldStyleError = function(obj) {
return typeof obj == "object" &&
["message", "code", "stack"].every(c => obj.hasOwnProperty(c));
}
error.isSuccess = status => status === "success";

/**
* Checks if obj is an instance of the Error prototype in a safe manner.
Expand All @@ -97,7 +85,7 @@ error.isError = function(val) {
} else if ("result" in val && val.result in XPCOM_EXCEPTIONS) {
return true;
} else {
return Object.getPrototypeOf(val) == "Error" || isOldStyleError(val);
return Object.getPrototypeOf(val) == "Error";
}
};

Expand All @@ -106,8 +94,7 @@ error.isError = function(val) {
*/
error.isWebDriverError = function(obj) {
return error.isError(obj) &&
(("name" in obj && errors.indexOf(obj.name) > 0) ||
isOldStyleError(obj));
("name" in obj && errors.indexOf(obj.name) > 0);
};

/**
Expand Down Expand Up @@ -147,23 +134,20 @@ this.WebDriverError = function(msg) {
this.name = "WebDriverError";
this.message = msg;
this.status = "webdriver error";
this.code = 500; // overridden
};
WebDriverError.prototype = Object.create(Error.prototype);

this.ElementNotAccessibleError = function(msg) {
WebDriverError.call(this, msg);
this.name = "ElementNotAccessibleError";
this.status = "element not accessible";
this.code = 56;
};
ElementNotAccessibleError.prototype = Object.create(WebDriverError.prototype);

this.ElementNotVisibleError = function(msg) {
WebDriverError.call(this, msg);
this.name = "ElementNotVisibleError";
this.status = "element not visible";
this.code = 11;
};
ElementNotVisibleError.prototype = Object.create(WebDriverError.prototype);

Expand All @@ -172,7 +156,6 @@ this.FrameSendFailureError = function(frame) {
WebDriverError.call(this, this.message);
this.name = "FrameSendFailureError";
this.status = "frame send failure error";
this.code = 55;
this.frame = frame;
this.errMsg = `${this.message} ${this.frame}; frame not responding.`;
};
Expand All @@ -183,7 +166,6 @@ this.FrameSendNotInitializedError = function(frame) {
WebDriverError.call(this, this.message);
this.name = "FrameSendNotInitializedError";
this.status = "frame send not initialized error";
this.code = 54;
this.frame = frame;
this.errMsg = `${this.message} ${this.frame}; frame has closed.`;
};
Expand All @@ -193,23 +175,20 @@ this.IllegalArgumentError = function(msg) {
WebDriverError.call(this, msg);
this.name = "IllegalArgumentError";
this.status = "illegal argument";
this.code = 13; // unknown error
};
IllegalArgumentError.prototype = Object.create(WebDriverError.prototype);

this.InvalidElementStateError = function(msg) {
WebDriverError.call(this, msg);
this.name = "InvalidElementStateError";
this.status = "invalid element state";
this.code = 12;
};
InvalidElementStateError.prototype = Object.create(WebDriverError.prototype);

this.InvalidSelectorError = function(msg) {
WebDriverError.call(this, msg);
this.name = "InvalidSelectorError";
this.status = "invalid selector";
this.code = 32;
};
InvalidSelectorError.prototype = Object.create(WebDriverError.prototype);

Expand Down Expand Up @@ -264,7 +243,6 @@ this.JavaScriptError = function(err, fnName, file, line, script) {
WebDriverError.call(this, msg);
this.name = "JavaScriptError";
this.status = "javascript error";
this.code = 17;
this.stack = trace;
};
JavaScriptError.prototype = Object.create(WebDriverError.prototype);
Expand All @@ -273,64 +251,55 @@ this.NoAlertOpenError = function(msg) {
WebDriverError.call(this, msg);
this.name = "NoAlertOpenError";
this.status = "no such alert";
this.code = 27;
}
NoAlertOpenError.prototype = Object.create(WebDriverError.prototype);

this.NoSuchElementError = function(msg) {
WebDriverError.call(this, msg);
this.name = "NoSuchElementError";
this.status = "no such element";
this.code = 7;
};
NoSuchElementError.prototype = Object.create(WebDriverError.prototype);

this.NoSuchFrameError = function(msg) {
WebDriverError.call(this, msg);
this.name = "NoSuchFrameError";
this.status = "no such frame";
this.code = 8;
};
NoSuchFrameError.prototype = Object.create(WebDriverError.prototype);

this.NoSuchWindowError = function(msg) {
WebDriverError.call(this, msg);
this.name = "NoSuchWindowError";
this.status = "no such window";
this.code = 23;
};
NoSuchWindowError.prototype = Object.create(WebDriverError.prototype);

this.ScriptTimeoutError = function(msg) {
WebDriverError.call(this, msg);
this.name = "ScriptTimeoutError";
this.status = "script timeout";
this.code = 28;
};
ScriptTimeoutError.prototype = Object.create(WebDriverError.prototype);

this.SessionNotCreatedError = function(msg) {
WebDriverError.call(this, msg);
this.name = "SessionNotCreatedError";
this.status = "session not created";
// should be 33 to match Selenium
this.code = 71;
};
SessionNotCreatedError.prototype = Object.create(WebDriverError.prototype);

this.StaleElementReferenceError = function(msg) {
WebDriverError.call(this, msg);
this.name = "StaleElementReferenceError";
this.status = "stale element reference";
this.code = 10;
};
StaleElementReferenceError.prototype = Object.create(WebDriverError.prototype);

this.TimeoutError = function(msg) {
WebDriverError.call(this, msg);
this.name = "TimeoutError";
this.status = "timeout";
this.code = 21;
};
TimeoutError.prototype = Object.create(WebDriverError.prototype);

Expand All @@ -346,22 +315,19 @@ this.UnknownCommandError = function(msg) {
WebDriverError.call(this, msg);
this.name = "UnknownCommandError";
this.status = "unknown command";
this.code = 9;
};
UnknownCommandError.prototype = Object.create(WebDriverError.prototype);

this.UnknownError = function(msg) {
WebDriverError.call(this, msg);
this.name = "UnknownError";
this.status = "unknown error";
this.code = 13;
};
UnknownError.prototype = Object.create(WebDriverError.prototype);

this.UnsupportedOperationError = function(msg) {
WebDriverError.call(this, msg);
this.name = "UnsupportedOperationError";
this.status = "unsupported operation";
this.code = 405;
};
UnsupportedOperationError.prototype = Object.create(WebDriverError.prototype);
15 changes: 8 additions & 7 deletions testing/marionette/listener.js
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,8 @@ function createExecuteContentSandbox(aWindow, timeout) {
inactivityTimeoutId = null;
}
};
sandbox.finish = function sandbox_finish() {

sandbox.finish = function() {
if (asyncTestRunning) {
sandbox.asyncComplete(marionette.generate_results(), sandbox.asyncTestCommandId);
} else {
Expand Down Expand Up @@ -699,11 +700,6 @@ function executeWithCallback(msg, useFinish) {
}
sandbox.tag = script;

// Error code 28 is scriptTimeout, but spec says execute_async should return 21 (Timeout),
// see http://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/execute_async.
// However Selenium code returns 28, see
// http://code.google.com/p/selenium/source/browse/trunk/javascript/firefox-driver/js/evaluate.js.
// We'll stay compatible with the Selenium code.
asyncTestTimeoutId = curFrame.setTimeout(function() {
sandbox.asyncComplete(new ScriptTimeoutError("timed out"), asyncTestCommandId);
}, msg.json.timeout);
Expand Down Expand Up @@ -1445,7 +1441,7 @@ function isElementDisplayed(msg) {
* the element that will be checked
* 'propertyName' is the CSS rule that is being requested
*/
function getElementValueOfCssProperty(msg){
function getElementValueOfCssProperty(msg) {
let command_id = msg.json.command_id;
let propertyName = msg.json.propertyName;
try {
Expand Down Expand Up @@ -1617,6 +1613,11 @@ function clearElement(msg) {
}
sendOk(command_id);
} catch (e) {
// Bug 964738: Newer atoms contain status codes which makes wrapping
// this in an error prototype that has a status property unnecessary
if (e.name == "InvalidElementStateError") {
e = new InvalidElementStateError(e.message);
}
sendError(e, command_id);
}
}
Expand Down

0 comments on commit 40edcdc

Please sign in to comment.