tor-browser

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

suppressed-error-handling-scopes.js (4092B)


      1 // |jit-test| skip-if: !getBuildConfiguration("explicit-resource-management"); --enable-explicit-resource-management
      2 
      3 load(libdir + "asserts.js");
      4 
      5 {
      6  const disposed = [];
      7  function testExceptionBeforeDispose() {
      8    throw new Error("test");
      9    using d = {
     10      [Symbol.dispose]() {
     11        disposed.push(1);
     12      }
     13    };
     14  }
     15  assertThrowsInstanceOf(testExceptionOutsideDispose, Error);
     16  assertEq(disposed.length, 0);
     17 }
     18 
     19 {
     20  const disposed = [];
     21  function testExceptionOutsideDispose() {
     22    using d = {
     23      [Symbol.dispose]() {
     24        disposed.push(1);
     25      }
     26    };
     27 
     28    throw new Error("test");
     29  }
     30  assertThrowsInstanceOf(testExceptionOutsideDispose, Error);
     31  assertArrayEq(disposed, [1]);
     32 }
     33 
     34 {
     35  const disposed = [];
     36  function testExceptionInsideDispose() {
     37    using d = {
     38      [Symbol.dispose]() {
     39        disposed.push(1);
     40        throw new Error("test");
     41      }
     42    };
     43  }
     44  assertThrowsInstanceOf(testExceptionInsideDispose, Error);
     45  assertArrayEq(disposed, [1]);
     46 }
     47 
     48 {
     49  const disposed = [];
     50  const errorsToThrow = [new Error("test1"), new Error("test2")];
     51  function testExceptionInsideAndOutsideDispose() {
     52    using d = {
     53      [Symbol.dispose]() {
     54        disposed.push(1);
     55        throw errorsToThrow[0];
     56      }
     57    };
     58 
     59    throw errorsToThrow[1];
     60  }
     61  assertSuppressionChain(testExceptionInsideAndOutsideDispose, errorsToThrow);
     62  assertArrayEq(disposed, [1]);
     63 }
     64 
     65 {
     66  const disposed = [];
     67  const errorsToThrow = [new Error("test1"), new Error("test2"), new Error("test3")];
     68  function testMultipleDisposeWithException() {
     69    using d1 = {
     70      [Symbol.dispose]() {
     71        disposed.push(1);
     72        throw errorsToThrow[0];
     73      }
     74    };
     75    using d2 = {
     76      [Symbol.dispose]() {
     77        disposed.push(2);
     78        throw errorsToThrow[1];
     79      }
     80    };
     81    using d3 = {
     82      [Symbol.dispose]() {
     83        disposed.push(3);
     84        throw errorsToThrow[2];
     85      }
     86    }
     87  }
     88  assertSuppressionChain(testMultipleDisposeWithException, errorsToThrow);
     89  assertArrayEq(disposed, [3, 2, 1]);
     90 }
     91 
     92 {
     93  const disposed = [];
     94  const errorsToThrow = [new Error("test1"), new Error("test2"), new Error("test3"), new Error("test4")];
     95  function testMultipleDisposeWithThrowsAndOutsideThrow() {
     96    using d1 = {
     97      [Symbol.dispose]() {
     98        disposed.push(1);
     99        throw errorsToThrow[0];
    100      }
    101    };
    102    using d2 = {
    103      [Symbol.dispose]() {
    104        disposed.push(2);
    105        throw errorsToThrow[1];
    106      }
    107    };
    108    using d3 = {
    109      [Symbol.dispose]() {
    110        disposed.push(3);
    111        throw errorsToThrow[2];
    112      }
    113    }
    114    throw errorsToThrow[3];
    115  }
    116  assertSuppressionChain(testMultipleDisposeWithThrowsAndOutsideThrow, errorsToThrow);
    117  assertArrayEq(disposed, [3, 2, 1]);
    118 }
    119 
    120 {
    121  const disposed = [];
    122  const errorsToThrow = [new Error("test1"), new Error("test2"), new Error("test3")];
    123  function testDisposeWithThrowInAnInnerScope() {
    124    using d1 = {
    125      [Symbol.dispose]() {
    126        disposed.push(1);
    127        throw errorsToThrow[0];
    128      }
    129    };
    130    {
    131      using d2 = {
    132        [Symbol.dispose]() {
    133          disposed.push(2);
    134          throw errorsToThrow[1];
    135        }
    136      };
    137      {
    138        let a = 0, b = () => a;
    139        throw errorsToThrow[2];
    140      }
    141    }
    142  }
    143  assertSuppressionChain(testDisposeWithThrowInAnInnerScope, errorsToThrow);
    144  assertArrayEq(disposed, [2, 1]);
    145 }
    146 
    147 {
    148  globalThis.disposedModule = [];
    149  globalThis.errorsToThrowModule = [new Error('test1'), new Error('test2'), new Error('test3')];
    150  const m = parseModule(`
    151    using x = {
    152      [Symbol.dispose]() {
    153        globalThis.disposedModule.push(1);
    154        throw globalThis.errorsToThrowModule[0];
    155      }
    156    }
    157    using y = {
    158      [Symbol.dispose]() {
    159        globalThis.disposedModule.push(2);
    160        throw globalThis.errorsToThrowModule[1];
    161      }
    162    }
    163    throw globalThis.errorsToThrowModule[2];
    164  `);
    165  moduleLink(m);
    166  let e = null;
    167  moduleEvaluate(m).catch((err) => { e = err; });
    168  drainJobQueue();
    169  assertSuppressionChain(() => { throw e; }, globalThis.errorsToThrowModule);
    170  assertArrayEq(globalThis.disposedModule, [2, 1]);
    171 }