tor-browser

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

browser_handle_command_errors.js (6477B)


      1 /* Any copyright is dedicated to the Public Domain.
      2 * http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const { RootMessageHandler } = ChromeUtils.importESModule(
      7  "chrome://remote/content/shared/messagehandler/RootMessageHandler.sys.mjs"
      8 );
      9 
     10 // Check that errors from WindowGlobal modules can be caught by the consumer
     11 // of the RootMessageHandler.
     12 add_task(async function test_module_error() {
     13  const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
     14 
     15  const rootMessageHandler = createRootMessageHandler("session-id-error");
     16 
     17  info("Call a module method which will throw");
     18 
     19  await Assert.rejects(
     20    rootMessageHandler.handleCommand({
     21      moduleName: "commandwindowglobalonly",
     22      commandName: "testError",
     23      destination: {
     24        type: WindowGlobalMessageHandler.type,
     25        id: browsingContextId,
     26      },
     27    }),
     28    err => err.message.includes("error-from-module"),
     29    "Error from window global module caught"
     30  );
     31 
     32  rootMessageHandler.destroy();
     33 });
     34 
     35 // Check that sending commands to incorrect destinations creates an error which
     36 // can be caught by the consumer of the RootMessageHandler.
     37 add_task(async function test_destination_error() {
     38  const rootMessageHandler = createRootMessageHandler("session-id-error");
     39 
     40  const fakeBrowsingContextId = -1;
     41  ok(
     42    !BrowsingContext.get(fakeBrowsingContextId),
     43    "No browsing context matches fakeBrowsingContextId"
     44  );
     45 
     46  info("Call a valid module method, but on a non-existent browsing context id");
     47  Assert.throws(
     48    () =>
     49      rootMessageHandler.handleCommand({
     50        moduleName: "commandwindowglobalonly",
     51        commandName: "testOnlyInWindowGlobal",
     52        destination: {
     53          type: WindowGlobalMessageHandler.type,
     54          id: fakeBrowsingContextId,
     55        },
     56      }),
     57    err => err.message == `Unable to find a BrowsingContext for id "-1"`
     58  );
     59 
     60  rootMessageHandler.destroy();
     61 });
     62 
     63 add_task(async function test_invalid_module_error() {
     64  const rootMessageHandler = createRootMessageHandler(
     65    "session-id-missing_module"
     66  );
     67 
     68  info("Attempt to call a Root module which has a syntax error");
     69  Assert.throws(
     70    () =>
     71      rootMessageHandler.handleCommand({
     72        moduleName: "invalid",
     73        commandName: "someMethod",
     74        destination: {
     75          type: RootMessageHandler.type,
     76        },
     77      }),
     78    err =>
     79      err.name === "SyntaxError" &&
     80      err.message == "expected expression, got ';'"
     81  );
     82 
     83  rootMessageHandler.destroy();
     84 });
     85 
     86 add_task(async function test_missing_root_module_error() {
     87  const rootMessageHandler = createRootMessageHandler(
     88    "session-id-missing_module"
     89  );
     90 
     91  info("Attempt to call a Root module which doesn't exist");
     92  Assert.throws(
     93    () =>
     94      rootMessageHandler.handleCommand({
     95        moduleName: "missingmodule",
     96        commandName: "someMethod",
     97        destination: {
     98          type: RootMessageHandler.type,
     99        },
    100      }),
    101    err =>
    102      err.name == "UnsupportedCommandError" &&
    103      err.message ==
    104        `missingmodule.someMethod not supported for destination ROOT`
    105  );
    106 
    107  rootMessageHandler.destroy();
    108 });
    109 
    110 add_task(async function test_missing_windowglobal_module_error() {
    111  const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
    112  const rootMessageHandler = createRootMessageHandler(
    113    "session-id-missing_windowglobal_module"
    114  );
    115 
    116  info("Attempt to call a WindowGlobal module which doesn't exist");
    117  Assert.throws(
    118    () =>
    119      rootMessageHandler.handleCommand({
    120        moduleName: "missingmodule",
    121        commandName: "someMethod",
    122        destination: {
    123          type: WindowGlobalMessageHandler.type,
    124          id: browsingContextId,
    125        },
    126      }),
    127    err =>
    128      err.name == "UnsupportedCommandError" &&
    129      err.message ==
    130        `missingmodule.someMethod not supported for destination WINDOW_GLOBAL`
    131  );
    132 
    133  rootMessageHandler.destroy();
    134 });
    135 
    136 add_task(async function test_missing_root_method_error() {
    137  const rootMessageHandler = createRootMessageHandler(
    138    "session-id-missing_root_method"
    139  );
    140 
    141  info("Attempt to call an invalid method on a Root module");
    142  Assert.throws(
    143    () =>
    144      rootMessageHandler.handleCommand({
    145        moduleName: "command",
    146        commandName: "wrongMethod",
    147        destination: {
    148          type: RootMessageHandler.type,
    149        },
    150      }),
    151    err =>
    152      err.name == "UnsupportedCommandError" &&
    153      err.message == `command.wrongMethod not supported for destination ROOT`
    154  );
    155 
    156  rootMessageHandler.destroy();
    157 });
    158 
    159 add_task(async function test_missing_windowglobal_method_error() {
    160  const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
    161  const rootMessageHandler = createRootMessageHandler(
    162    "session-id-missing_windowglobal_method"
    163  );
    164 
    165  info("Attempt to call an invalid method on a WindowGlobal module");
    166  Assert.throws(
    167    () =>
    168      rootMessageHandler.handleCommand({
    169        moduleName: "commandwindowglobalonly",
    170        commandName: "wrongMethod",
    171        destination: {
    172          type: WindowGlobalMessageHandler.type,
    173          id: browsingContextId,
    174        },
    175      }),
    176    err =>
    177      err.name == "UnsupportedCommandError" &&
    178      err.message ==
    179        `commandwindowglobalonly.wrongMethod not supported for destination WINDOW_GLOBAL`
    180  );
    181 
    182  rootMessageHandler.destroy();
    183 });
    184 
    185 /**
    186 * This test checks that even if a command is rerouted to another command after
    187 * the RootMessageHandler, we still check the new command and log a useful
    188 * error message.
    189 *
    190 * This illustrates why it is important to perform the command check at each
    191 * layer of the MessageHandler network.
    192 */
    193 add_task(async function test_missing_intermediary_method_error() {
    194  const browsingContextId = gBrowser.selectedBrowser.browsingContext.id;
    195  const rootMessageHandler = createRootMessageHandler(
    196    "session-id-missing_intermediary_method"
    197  );
    198 
    199  info(
    200    "Call a (valid) command that relies on another (missing) command on a WindowGlobal module"
    201  );
    202  await Assert.rejects(
    203    rootMessageHandler.handleCommand({
    204      moduleName: "commandwindowglobalonly",
    205      commandName: "testMissingIntermediaryMethod",
    206      destination: {
    207        type: WindowGlobalMessageHandler.type,
    208        id: browsingContextId,
    209      },
    210    }),
    211    err =>
    212      err.name == "UnsupportedCommandError" &&
    213      err.message ==
    214        `commandwindowglobalonly.missingMethod not supported for destination WINDOW_GLOBAL`
    215  );
    216 
    217  rootMessageHandler.destroy();
    218 });