async-disposal-during-throw-loop.js (2227B)
1 // |jit-test| skip-if: !getBuildConfiguration("explicit-resource-management"); --enable-explicit-resource-management 2 3 load(libdir + "asserts.js"); 4 5 class CustomError extends Error {} 6 7 { 8 const disposed = []; 9 let catchCalled = false; 10 async function testAsyncDisposalInLoopDuringThrow() { 11 const disposables = [ 12 { 13 val: "a", 14 [Symbol.asyncDispose]() { 15 disposed.push(this.val); 16 } 17 }, 18 { 19 val: "b", 20 [Symbol.asyncDispose]() { 21 disposed.push(this.val); 22 } 23 }, 24 { 25 val: "c", 26 [Symbol.asyncDispose]() { 27 disposed.push(this.val); 28 } 29 } 30 ]; 31 for (await using d of disposables) { 32 if (d.val === "b") { 33 throw new CustomError(); 34 } 35 } 36 } 37 testAsyncDisposalInLoopDuringThrow().catch((e) => { 38 catchCalled = true; 39 assertEq(e instanceof CustomError, true); 40 }); 41 drainJobQueue(); 42 assertEq(catchCalled, true); 43 assertArrayEq(disposed, ["a", "b"]); 44 } 45 46 { 47 const disposed = []; 48 let catchCalled = false; 49 async function testDisposalInLoopWithIteratorClose() { 50 const disposables = [ 51 { 52 val: "a", 53 [Symbol.dispose]() { 54 disposed.push(this.val); 55 } 56 }, 57 { 58 val: "b", 59 [Symbol.dispose]() { 60 disposed.push(this.val); 61 } 62 }, 63 { 64 val: "c", 65 [Symbol.dispose]() { 66 disposed.push(this.val); 67 } 68 } 69 ]; 70 const iterable = { 71 [Symbol.iterator]() { 72 let i = 0; 73 return { 74 next() { 75 if (i === disposables.length) { 76 return { done: true }; 77 } 78 return { value: disposables[i++], done: false }; 79 }, 80 return() { 81 disposed.push("return"); 82 return { done: true }; 83 } 84 } 85 } 86 } 87 for (await using d of iterable) { 88 if (d.val === "b") { 89 throw new CustomError(); 90 } 91 } 92 } 93 testDisposalInLoopWithIteratorClose().catch((e) => { 94 catchCalled = true; 95 assertEq(e instanceof CustomError, true); 96 }); 97 drainJobQueue(); 98 assertEq(catchCalled, true); 99 assertArrayEq(disposed, ["a", "b", "return"]); 100 }