remote/Error.jsm
author Andreas Tolfsen <ato@sny.no>
Wed, 13 Mar 2019 14:35:57 +0000
changeset 524707 95f4b83aed87e9d8638987cf30b40f5ac6cd1821
parent 524125 06c54b40f31249275aebae31d17a1aa3add93058
child 529636 c1ee8401a2c7fdf5d5fe2653f96616657648fc44
permissions -rw-r--r--
bug 1534827: remote: fix constants in transitionToLoadFlag; r=yulia The transitionType is converted into undefined because there is a typo in the constants. These should be "FLAGS" rather than "FLAG". Thanks-to: Mark Banner <standard8@mozilla.com> Differential Revision: https://phabricator.services.mozilla.com/D23315

/* 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(formatError(this));
  }

  toString({stack = false} = {}) {
    return RemoteAgentError.format(this, {stack});
  }

  static format(e, {stack = false} = {}) {
    return formatError(e, {stack});
  }
}

/**
 * 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());
  }

  toString() {
    return formatError(this, {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 {}

function formatError(error, {stack = false} = {}) {
  const ls = [];

  ls.push(`${error.name}: ${error.message ? `${error.message}:` : ""}`);

  if (stack && error.stack) {
    const stack = error.stack.trim().split("\n");
    ls.push(stack.map(line => `\t${line}`).join("\n"));

    if (error.cause) {
      ls.push("caused by: " + formatError(error.cause, {stack}));
    }
  }

  return ls.join("\n");
}