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 }