diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /remote/Error.jsm | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'remote/Error.jsm')
-rw-r--r-- | remote/Error.jsm | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/remote/Error.jsm b/remote/Error.jsm new file mode 100644 index 0000000000..d7a83400cb --- /dev/null +++ b/remote/Error.jsm @@ -0,0 +1,137 @@ +/* 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"; + +var EXPORTED_SYMBOLS = [ + "FatalError", + "RemoteAgentError", + "UnknownMethodError", + "UnsupportedError", +]; + +const { Log } = ChromeUtils.import("chrome://remote/content/Log.jsm"); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); +const { XPCOMUtils } = ChromeUtils.import( + "resource://gre/modules/XPCOMUtils.jsm" +); + +XPCOMUtils.defineLazyGetter(this, "log", Log.get); + +class RemoteAgentError extends Error { + constructor(message = "", cause = undefined) { + cause = cause || message; + super(cause); + + this.name = this.constructor.name; + this.message = message; + this.cause = cause; + + this.notify(); + } + + notify() { + Cu.reportError(this); + log.error(this.toString({ stack: true })); + } + + toString({ stack = false } = {}) { + return RemoteAgentError.format(this, { stack }); + } + + static format(e, { stack = false } = {}) { + return formatError(e, { stack }); + } + + /** + * Takes a serialised CDP error and reconstructs it + * as a RemoteAgentError. + * + * The error must be of this form: + * + * {"message": "TypeError: foo is not a function\n + * execute@chrome://remote/content/sessions/Session.jsm:73:39\n + * onMessage@chrome://remote/content/sessions/TabSession.jsm:65:20"} + * + * This approach has the notable deficiency that it cannot deal + * with causes to errors because of the unstructured nature of CDP + * errors. A possible future improvement would be to extend the + * error serialisation to include discrete fields for each data + * property. + * + * @param {Object} json + * CDP error encoded as a JSON object, which must have a + * "message" field, where the first line will make out the error + * message and the subsequent lines the stacktrace. + * + * @return {RemoteAgentError} + */ + static fromJSON(json) { + const [message, ...stack] = json.message.split("\n"); + const err = new RemoteAgentError(); + err.message = message.slice(0, -1); + err.stack = stack.map(s => s.trim()).join("\n"); + err.cause = null; + return err; + } +} + +/** + * A fatal error that it is not possible to recover from + * or send back to the client. + * + * Constructing this error will force the application to quit. + */ +class FatalError extends RemoteAgentError { + constructor(...args) { + super(...args); + this.quit(); + } + + notify() { + log.fatal(this.toString({ stack: true })); + } + + quit(mode = Ci.nsIAppStartup.eForceQuit) { + Services.startup.quit(mode); + } +} + +/** When an operation is not yet implemented. */ +class UnsupportedError extends RemoteAgentError {} + +/** The requested remote method does not exist. */ +class UnknownMethodError extends RemoteAgentError { + constructor(domain, command = null) { + if (command) { + super(`${domain}.${command}`); + } else { + super(domain); + } + } +} + +function formatError(error, { stack = false } = {}) { + const els = []; + + els.push(error.name); + if (error.message) { + els.push(": "); + els.push(error.message); + } + + if (stack && error.stack) { + els.push(":\n"); + + const stack = error.stack.trim().split("\n"); + els.push(stack.map(line => `\t${line}`).join("\n")); + + if (error.cause) { + els.push("\n"); + els.push("caused by: " + formatError(error.cause, { stack })); + } + } + + return els.join(""); +} |