[explicit-resource-management] Complete exception handling

This CL completes the exception handling (promise rejection) for
async explicit resource management.

Bug: 42203814
Change-Id: Ide4f05df14f74e68b7aa120230f1b1ae33ce8adc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5692882
Commit-Queue: Rezvan Mahdavi Hezaveh <rezvan@chromium.org>
Reviewed-by: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#95748}
This commit is contained in:
Rezvan Mahdavi Hezaveh 2024-08-28 10:23:32 -07:00 committed by test262-merge-bot
parent 6c1116d45f
commit d62fa93c8f
13 changed files with 422 additions and 2 deletions

View File

@ -0,0 +1,25 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Test exception handling when async dispose method throws.
includes: [asyncHelpers.js]
flags: [async]
features: [explicit-resource-management]
---*/
// Dispose method throws -----------------------------
asyncTest(async function() {
async function TestDisposeMethodThrows() {
await using x = {
value: 1,
async [Symbol.asyncDispose]() {
await 0;
throw new Test262Error('Symbol.asyncDispose is throwing!');
}
};
};
await assert.throwsAsync(
Test262Error, () => TestDisposeMethodThrows(),
'Symbol.asyncDispose is throwing!');
});

View File

@ -0,0 +1,24 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Test exception handling when dispose method throws.
includes: [asyncHelpers.js]
flags: [async]
features: [explicit-resource-management]
---*/
// Dispose method throws -----------------------------
asyncTest(async function() {
async function TestDisposeMethodThrows() {
await using x = {
value: 1,
[Symbol.asyncDispose]() {
throw new Test262Error('Symbol.asyncDispose is throwing!');
}
};
};
await assert.throwsAsync(
Test262Error, () => TestDisposeMethodThrows(),
'Symbol.asyncDispose is throwing!');
});

View File

@ -0,0 +1,31 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Test exception handling when dispose method throws.
includes: [asyncHelpers.js]
flags: [async]
features: [explicit-resource-management]
---*/
// Dispose method throws -----------------------------
asyncTest(async function() {
async function TestDisposeMethodThrows() {
await using x = {
value: 1,
[Symbol.asyncDispose]() {
throw new Test262Error('Symbol.asyncDispose is throwing!');
}
};
using y = {
value: 1,
[Symbol.dispose]() {
return 42;
}
};
};
await assert.throwsAsync(
Test262Error, () => TestDisposeMethodThrows(),
'Symbol.asyncDispose is throwing!');
});

View File

@ -0,0 +1,31 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Test exception handling when dispose method throws.
includes: [asyncHelpers.js]
flags: [async]
features: [explicit-resource-management]
---*/
// Dispose method throws -----------------------------
asyncTest(async function() {
async function TestDisposeMethodThrows() {
await using x = {
value: 1,
[Symbol.asyncDispose]() {
return 42;
}
};
using y = {
value: 1,
[Symbol.dispose]() {
throw new Test262Error('Symbol.dispose is throwing!');
}
};
};
await assert.throwsAsync(
Test262Error, () => TestDisposeMethodThrows(),
'Symbol.dispose is throwing!');
});

View File

@ -0,0 +1,48 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Throws a suppressed error from errors in sync and async disposal.
includes: [asyncHelpers.js]
flags: [async]
features: [explicit-resource-management]
---*/
asyncTest(async function() {
let firstDisposeError = new Test262Error('The Symbol.dispose is throwing!');
let secondDisposeError =
new Test262Error('The Symbol.asyncDispose is throwing!');
async function TestTwoDisposeMethodsThrow() {
using x = {
value: 1,
[Symbol.dispose]() {
throw firstDisposeError;
}
};
await using y = {
value: 1,
async[Symbol.asyncDispose]() {
throw secondDisposeError;
}
};
};
await assert.throwsAsync(
SuppressedError, () => TestTwoDisposeMethodsThrow(),
'An error was suppressed during disposal');
async function RunTestTwoDisposeMethodsThrow() {
try {
TestTwoDisposeMethodsThrow();
} catch (error) {
assert(
error instanceof SuppressedError,
'error is an instanceof SuppressedError');
assert.sameValue(error.error, firstDisposeError, 'error.error');
assert.sameValue(
error.suppressed, secondDisposeError, 'error.suppressed');
}
}
await RunTestTwoDisposeMethodsThrow();
});

View File

@ -0,0 +1,49 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Throws a suppressed error from errors in disposal.
includes: [asyncHelpers.js]
flags: [async]
features: [explicit-resource-management]
---*/
// A suppressed error from two errors in disposal -----------------------------
asyncTest(async function() {
let firstDisposeError = new Test262Error('The Symbol.dispose is throwing!');
let secondDisposeError =
new Test262Error('The Symbol.asyncDispose is throwing!');
async function TestTwoDisposeMethodsThrow() {
using x = {
value: 1,
[Symbol.dispose]() {
throw firstDisposeError;
}
};
await using y = {
value: 1,
[Symbol.asyncDispose]() {
throw secondDisposeError;
}
};
};
await assert.throwsAsync(
SuppressedError, () => TestTwoDisposeMethodsThrow(),
'An error was suppressed during disposal');
async function RunTestTwoDisposeMethodsThrow() {
try {
TestTwoDisposeMethodsThrow();
} catch (error) {
assert(
error instanceof SuppressedError,
'error is an instanceof SuppressedError');
assert.sameValue(error.error, firstDisposeError, 'error.error');
assert.sameValue(
error.suppressed, secondDisposeError, 'error.suppressed');
}
}
await RunTestTwoDisposeMethodsThrow();
});

View File

@ -0,0 +1,25 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Test if exception handling is correct from Symbol.dispose.
includes: [asyncHelpers.js]
flags: [async]
features: [explicit-resource-management]
---*/
// sync dispose method throws ----------------
asyncTest(async function() {
async function TestDisposeMethodThrows() {
await using x = {
value: 1,
[Symbol.dispose]() {
throw new Test262Error('Symbol.dispose is throwing!');
}
};
}
await assert.throwsAsync(
Test262Error, () => TestDisposeMethodThrows(),
'Symbol.dispose is throwing!');
});

View File

@ -0,0 +1,50 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Throws a suppressed error from errors in disposal.
includes: [asyncHelpers.js]
flags: [async]
features: [explicit-resource-management]
---*/
// A suppressed error from two errors in disposal -----------------------------
asyncTest(async function() {
let firstDisposeError =
new Test262Error('The first Symbol.asyncDispose is throwing!');
let secondDisposeError =
new Test262Error('The second Symbol.asyncDispose is throwing!');
async function TestTwoDisposeMethodsThrow() {
await using x = {
value: 1,
[Symbol.asyncDispose]() {
throw firstDisposeError;
}
};
await using y = {
value: 1,
[Symbol.asyncDispose]() {
throw secondDisposeError;
}
};
};
await assert.throwsAsync(
SuppressedError, () => TestTwoDisposeMethodsThrow(),
'An error was suppressed during disposal');
async function RunTestTwoDisposeMethodsThrow() {
try {
TestTwoDisposeMethodsThrow();
} catch (error) {
assert(
error instanceof SuppressedError,
'error is an instanceof SuppressedError');
assert.sameValue(error.error, firstDisposeError, 'error.error');
assert.sameValue(
error.suppressed, secondDisposeError, 'error.suppressed');
}
}
await RunTestTwoDisposeMethodsThrow();
});

View File

@ -0,0 +1,41 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Throws a suppressed error from errors in try and in disposal
includes: [asyncHelpers.js]
flags: [async]
features: [explicit-resource-management]
---*/
// A suppressed error from an error in try block and an error in disposal
asyncTest(async function() {
let userCodeError = new Test262Error('User code is throwing!');
let disposeError = new Test262Error('Symbol.asyncDispose is throwing!');
async function TestDisposeMethodAndUserCodeThrow() {
await using x = {
value: 1,
[Symbol.asyncDispose]() {
throw disposeError;
}
};
throw userCodeError;
};
await assert.throwsAsync(
SuppressedError, () => TestDisposeMethodAndUserCodeThrow(),
'An error was suppressed during disposal');
async function RunTestDisposeMethodAndUserCodeThrow() {
try {
TestDisposeMethodAndUserCodeThrow();
} catch (error) {
assert(
error instanceof SuppressedError,
'error is an instanceof SuppressedError');
assert.sameValue(error.error, disposeError, 'error.error');
assert.sameValue(error.suppressed, userCodeError, 'error.suppressed');
}
}
RunTestDisposeMethodAndUserCodeThrow();
});

View File

@ -0,0 +1,47 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Throws a suppressed error from throwing undefined in disposal.
includes: [asyncHelpers.js]
flags: [async]
features: [explicit-resource-management]
---*/
asyncTest(async function() {
let firstDisposeError = undefined;
let secondDisposeError = undefined;
async function TestTwoDisposeMethodsThrowUndefined() {
await using x = {
value: 1,
[Symbol.asyncDispose]() {
throw firstDisposeError;
}
};
await using y = {
value: 1,
[Symbol.asyncDispose]() {
throw secondDisposeError;
}
};
};
await assert.throwsAsync(
SuppressedError, () => TestTwoDisposeMethodsThrowUndefined(),
'An error was suppressed during disposal');
async function RunTestTwoDisposeMethodsThrowUndefined() {
try {
TestTwoDisposeMethodsThrowUndefined();
} catch (error) {
assert(
error instanceof SuppressedError,
'error is an instanceof SuppressedError');
assert.sameValue(error.error, firstDisposeError, 'error.error');
assert.sameValue(
error.suppressed, secondDisposeError, 'error.suppressed');
}
}
await RunTestTwoDisposeMethodsThrowUndefined();
});

View File

@ -0,0 +1,25 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Test exception handling when user code throws.
includes: [asyncHelpers.js]
flags: [async]
features: [explicit-resource-management]
---*/
// User code throws -----------------------------
asyncTest(async function() {
async function TestUserCodeThrowsAfterUsingStatements() {
await using x = {
value: 1,
[Symbol.asyncDispose]() {
return 42;
}
};
throw new Test262Error('User code is throwing!');
};
await assert.throwsAsync(
Test262Error, () => TestUserCodeThrowsAfterUsingStatements(),
'User code is throwing!');
});

View File

@ -0,0 +1,26 @@
// Copyright (C) 2024 the V8 project authors. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/*---
description: Test exception handling when user code throws.
includes: [asyncHelpers.js]
flags: [async]
features: [explicit-resource-management]
---*/
// User code throws -----------------------------
asyncTest(async function() {
async function TestUserCodeThrowsBeforeUsingStatements() {
throw new Test262Error('User code is throwing!');
await using x = {
value: 1,
[Symbol.asyncDispose]() {
return 42;
}
};
};
await assert.throwsAsync(
Test262Error, () => TestUserCodeThrowsBeforeUsingStatements(),
'User code is throwing!')
});

View File

@ -13,10 +13,8 @@ asyncTest(async function() {
let values = [];
async function TestUsingWithoutDisposeMethod() {
{
await using x = {value: 1};
values.push(43);
}
};
await assert.throwsAsync(
TypeError, () => TestUsingWithoutDisposeMethod(), 'No dispose method');