tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DevToolsInfaillibleUtils.sys.mjs (2960B)


      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/. */
      4 
      5 /**
      6 * The 3 methods here are duplicated from ThreadSafeDevToolsUtils.js
      7 * The ones defined here are used from other sys.mjs files, mostly from the
      8 * NetworkObserver codebase, while the ones remaining in ThreadSafeDevToolsUtils.js
      9 * are used in commonjs modules, including modules which can be loaded in workers.
     10 *
     11 * sys.mjs modules are currently not supported in workers, see Bug 1247687.
     12 */
     13 
     14 /**
     15 * Report that |who| threw an exception, |exception|.
     16 */
     17 function reportException(who, exception) {
     18  const msg = `${who} threw an exception: ${safeErrorString(exception)}`;
     19  dump(msg + "\n");
     20 
     21  if (typeof console !== "undefined" && console && console.error) {
     22    console.error(exception);
     23  }
     24 }
     25 
     26 /**
     27 * Given a handler function that may throw, return an infallible handler
     28 * function that calls the fallible handler, and logs any exceptions it
     29 * throws.
     30 *
     31 * @param handler function
     32 *      A handler function, which may throw.
     33 * @param aName string
     34 *      A name for handler, for use in error messages. If omitted, we use
     35 *      handler.name.
     36 *
     37 * (SpiderMonkey does generate good names for anonymous functions, but we
     38 * don't have a way to get at them from JavaScript at the moment.)
     39 */
     40 function makeInfallible(handler, name = handler.name) {
     41  return function () {
     42    try {
     43      return handler.apply(this, arguments);
     44    } catch (ex) {
     45      let who = "Handler function";
     46      if (name) {
     47        who += " " + name;
     48      }
     49      reportException(who, ex);
     50      return undefined;
     51    }
     52  };
     53 }
     54 
     55 /**
     56 * Turn the |error| into a string, without fail.
     57 *
     58 * @param {Error|any} error
     59 */
     60 function safeErrorString(error) {
     61  try {
     62    let errorString = error.toString();
     63    if (typeof errorString == "string") {
     64      // Attempt to attach a stack to |errorString|. If it throws an error, or
     65      // isn't a string, don't use it.
     66      try {
     67        if (error.stack) {
     68          const stack = error.stack.toString();
     69          if (typeof stack == "string") {
     70            errorString += "\nStack: " + stack;
     71          }
     72        }
     73      } catch (ee) {
     74        // Ignore.
     75      }
     76 
     77      // Append additional line and column number information to the output,
     78      // since it might not be part of the stringified error.
     79      if (
     80        typeof error.lineNumber == "number" &&
     81        typeof error.columnNumber == "number"
     82      ) {
     83        errorString +=
     84          "Line: " + error.lineNumber + ", column: " + error.columnNumber;
     85      }
     86 
     87      return errorString;
     88    }
     89  } catch (ee) {
     90    // Ignore.
     91  }
     92 
     93  // We failed to find a good error description, so do the next best thing.
     94  return Object.prototype.toString.call(error);
     95 }
     96 
     97 export const DevToolsInfaillibleUtils = {
     98  makeInfallible,
     99  reportException,
    100  safeErrorString,
    101 };