зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1726800 - [remote] Use dedicated error class for command errors in MessageHandler r=webdriver-reviewers,whimboo
Add a dedicated Errors module to remote/shared/messagehandler, similar to shared/webdriver/Errors.jsm Errors thrown from content process MessageHandler are serialized before being forwarded to the parent process. We should probably make all errors inherit from a generic RemoteError class which would support the same serialization/deserialization API Differential Revision: https://phabricator.services.mozilla.com/D127620
This commit is contained in:
Родитель
76632e2d9d
Коммит
773ea0006d
|
@ -22,6 +22,7 @@ remote.jar:
|
|||
content/shared/WindowManager.jsm (shared/WindowManager.jsm)
|
||||
|
||||
# shared modules (messagehandler architecture)
|
||||
content/shared/messagehandler/Errors.jsm (shared/messagehandler/Errors.jsm)
|
||||
content/shared/messagehandler/MessageHandler.jsm (shared/messagehandler/MessageHandler.jsm)
|
||||
content/shared/messagehandler/MessageHandlerRegistry.jsm (shared/messagehandler/MessageHandlerRegistry.jsm)
|
||||
content/shared/messagehandler/Module.jsm (shared/messagehandler/Module.jsm)
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const EXPORTED_SYMBOLS = ["error"];
|
||||
|
||||
class MessageHandlerError extends Error {
|
||||
/**
|
||||
* @param {(string|Error)=} x
|
||||
* Optional string describing error situation or Error instance
|
||||
* to propagate.
|
||||
*/
|
||||
constructor(x) {
|
||||
super(x);
|
||||
this.name = this.constructor.name;
|
||||
this.status = "message handler error";
|
||||
|
||||
// Error's ctor does not preserve x' stack
|
||||
if (typeof x?.stack !== "undefined") {
|
||||
this.stack = x.stack;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {Object.<string, string>}
|
||||
* JSON serialisation of error prototype.
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
error: this.status,
|
||||
message: this.message || "",
|
||||
stacktrace: this.stack || "",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Unmarshals a JSON error representation to the appropriate MessageHandler
|
||||
* error type.
|
||||
*
|
||||
* @param {Object.<string, string>} json
|
||||
* Error object.
|
||||
*
|
||||
* @return {Error}
|
||||
* Error prototype.
|
||||
*/
|
||||
static fromJSON(json) {
|
||||
if (typeof json.error == "undefined") {
|
||||
let s = JSON.stringify(json);
|
||||
throw new TypeError("Undeserialisable error type: " + s);
|
||||
}
|
||||
if (!STATUSES.has(json.error)) {
|
||||
throw new TypeError("Not of MessageHandlerError descent: " + json.error);
|
||||
}
|
||||
|
||||
let cls = STATUSES.get(json.error);
|
||||
let err = new cls();
|
||||
if ("message" in json) {
|
||||
err.message = json.message;
|
||||
}
|
||||
if ("stacktrace" in json) {
|
||||
err.stack = json.stacktrace;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A command could not be handled by the message handler network.
|
||||
*/
|
||||
class UnsupportedCommandError extends MessageHandlerError {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.status = "unsupported message handler command";
|
||||
}
|
||||
}
|
||||
|
||||
const STATUSES = new Map([
|
||||
["message handler error", MessageHandlerError],
|
||||
["unsupported message handler command", UnsupportedCommandError],
|
||||
]);
|
||||
|
||||
/** @namespace */
|
||||
this.error = {
|
||||
MessageHandlerError,
|
||||
UnsupportedCommandError,
|
||||
};
|
|
@ -0,0 +1,99 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const { error } = ChromeUtils.import(
|
||||
"chrome://remote/content/shared/messagehandler/Errors.jsm"
|
||||
);
|
||||
|
||||
// Note: this test file is similar to remote/shared/webdriver/test/xpcshell/test_Errors.js
|
||||
// because shared/webdriver/Errors.jsm and shared/messagehandler/Errors.jsm share
|
||||
// similar helpers.
|
||||
|
||||
add_test(function test_toJSON() {
|
||||
let e0 = new error.MessageHandlerError();
|
||||
let e0s = e0.toJSON();
|
||||
equal(e0s.error, "message handler error");
|
||||
equal(e0s.message, "");
|
||||
|
||||
let e1 = new error.MessageHandlerError("a");
|
||||
let e1s = e1.toJSON();
|
||||
equal(e1s.message, e1.message);
|
||||
|
||||
let e2 = new error.UnsupportedCommandError("foo");
|
||||
let e2s = e2.toJSON();
|
||||
equal(e2.status, e2s.error);
|
||||
equal(e2.message, e2s.message);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_fromJSON() {
|
||||
Assert.throws(
|
||||
() => error.MessageHandlerError.fromJSON({ error: "foo" }),
|
||||
/Not of MessageHandlerError descent/
|
||||
);
|
||||
Assert.throws(
|
||||
() => error.MessageHandlerError.fromJSON({ error: "Error" }),
|
||||
/Not of MessageHandlerError descent/
|
||||
);
|
||||
Assert.throws(
|
||||
() => error.MessageHandlerError.fromJSON({}),
|
||||
/Undeserialisable error type/
|
||||
);
|
||||
Assert.throws(
|
||||
() => error.MessageHandlerError.fromJSON(undefined),
|
||||
/TypeError/
|
||||
);
|
||||
|
||||
let e1 = new error.MessageHandlerError("1");
|
||||
let e1r = error.MessageHandlerError.fromJSON({
|
||||
error: "message handler error",
|
||||
message: "1",
|
||||
});
|
||||
ok(e1r instanceof error.MessageHandlerError);
|
||||
equal(e1r.name, e1.name);
|
||||
equal(e1r.status, e1.status);
|
||||
equal(e1r.message, e1.message);
|
||||
|
||||
let e2 = new error.UnsupportedCommandError("foo");
|
||||
let e2r = error.MessageHandlerError.fromJSON({
|
||||
error: "unsupported message handler command",
|
||||
message: "foo",
|
||||
});
|
||||
ok(e2r instanceof error.MessageHandlerError);
|
||||
ok(e2r instanceof error.UnsupportedCommandError);
|
||||
equal(e2r.name, e2.name);
|
||||
equal(e2r.status, e2.status);
|
||||
equal(e2r.message, e2.message);
|
||||
|
||||
// parity with toJSON
|
||||
let e3 = new error.UnsupportedCommandError("foo");
|
||||
let e3toJSON = e3.toJSON();
|
||||
let e3fromJSON = error.MessageHandlerError.fromJSON(e3toJSON);
|
||||
equal(e3toJSON.error, e3fromJSON.status);
|
||||
equal(e3toJSON.message, e3fromJSON.message);
|
||||
equal(e3toJSON.stacktrace, e3fromJSON.stack);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_MessageHandlerError() {
|
||||
let err = new error.MessageHandlerError("foo");
|
||||
equal("MessageHandlerError", err.name);
|
||||
equal("foo", err.message);
|
||||
equal("message handler error", err.status);
|
||||
ok(err instanceof error.MessageHandlerError);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_UnsupportedCommandError() {
|
||||
let e = new error.UnsupportedCommandError("foo");
|
||||
equal("UnsupportedCommandError", e.name);
|
||||
equal("foo", e.message);
|
||||
equal("unsupported message handler command", e.status);
|
||||
ok(e instanceof error.MessageHandlerError);
|
||||
|
||||
run_next_test();
|
||||
});
|
|
@ -0,0 +1,5 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
[test_Errors.js]
|
|
@ -8,6 +8,7 @@ BROWSER_CHROME_MANIFESTS += [
|
|||
]
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += [
|
||||
"messagehandler/test/xpcshell/xpcshell.ini",
|
||||
"test/xpcshell/xpcshell.ini",
|
||||
"webdriver/test/xpcshell/xpcshell.ini",
|
||||
]
|
||||
|
|
Загрузка…
Ссылка в новой задаче