Bug 1869647 - Mark hasStorageAccess.sub.https.window.html as intermittent after wpt...
[gecko.git] / remote / cdp / Error.sys.mjs
blobb047285649d1f976b5d3506179a5f35a8d2c2070
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 const lazy = {};
7 ChromeUtils.defineESModuleGetters(lazy, {
8   Log: "chrome://remote/content/shared/Log.sys.mjs",
9 });
11 ChromeUtils.defineLazyGetter(lazy, "logger", () =>
12   lazy.Log.get(lazy.Log.TYPES.CDP)
15 export class RemoteAgentError extends Error {
16   constructor(message = "", cause = undefined) {
17     cause = cause || message;
18     super(cause);
20     this.name = this.constructor.name;
21     this.message = message;
22     this.cause = cause;
24     this.notify();
25   }
27   notify() {
28     console.error(this);
29     lazy.logger.error(this.toString({ stack: true }));
30   }
32   toString({ stack = false } = {}) {
33     return RemoteAgentError.format(this, { stack });
34   }
36   static format(e, { stack = false } = {}) {
37     return formatError(e, { stack });
38   }
40   /**
41    * Takes a serialised CDP error and reconstructs it
42    * as a RemoteAgentError.
43    *
44    * The error must be of this form:
45    *
46    *     {"message": "TypeError: foo is not a function\n
47    *     execute@chrome://remote/content/cdp/sessions/Session.jsm:73:39\n
48    *     onMessage@chrome://remote/content/cdp/sessions/TabSession.jsm:65:20"}
49    *
50    * This approach has the notable deficiency that it cannot deal
51    * with causes to errors because of the unstructured nature of CDP
52    * errors.  A possible future improvement would be to extend the
53    * error serialisation to include discrete fields for each data
54    * property.
55    *
56    * @param {object} json
57    *     CDP error encoded as a JSON object, which must have a
58    *     "message" field, where the first line will make out the error
59    *     message and the subsequent lines the stacktrace.
60    *
61    * @returns {RemoteAgentError}
62    */
63   static fromJSON(json) {
64     const [message, ...stack] = json.message.split("\n");
65     const err = new RemoteAgentError();
66     err.message = message.slice(0, -1);
67     err.stack = stack.map(s => s.trim()).join("\n");
68     err.cause = null;
69     return err;
70   }
73 /**
74  * A fatal error that it is not possible to recover from
75  * or send back to the client.
76  *
77  * Constructing this error will force the application to quit.
78  */
79 export class FatalError extends RemoteAgentError {
80   constructor(...args) {
81     super(...args);
82     this.quit();
83   }
85   notify() {
86     lazy.logger.fatal(this.toString({ stack: true }));
87   }
89   quit(mode = Ci.nsIAppStartup.eForceQuit) {
90     Services.startup.quit(mode);
91   }
94 /** When an operation is not yet implemented. */
95 export class UnsupportedError extends RemoteAgentError {}
97 /** The requested remote method does not exist. */
98 export class UnknownMethodError extends RemoteAgentError {
99   constructor(domain, command = null) {
100     if (command) {
101       super(`${domain}.${command}`);
102     } else {
103       super(domain);
104     }
105   }
108 function formatError(error, { stack = false } = {}) {
109   const els = [];
111   els.push(error.name);
112   if (error.message) {
113     els.push(": ");
114     els.push(error.message);
115   }
117   if (stack && error.stack) {
118     els.push(":\n");
120     const stack = error.stack.trim().split("\n");
121     els.push(stack.map(line => `\t${line}`).join("\n"));
123     if (error.cause) {
124       els.push("\n");
125       els.push("caused by: " + formatError(error.cause, { stack }));
126     }
127   }
129   return els.join("");