Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion aos/AddDisposableResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ module.exports = function AddDisposableResource(disposeCapability, V, hint) {

var resource;
if (arguments.length < 4) { // step 1
if (V == null && hint === 'SYNC_DISPOSE') {
if (V == null && hint === 'SYNC-DISPOSE') {
return 'UNUSED'; // step 1.a
}
resource = CreateDisposableResource(V, hint); // step 1.c
Expand Down
29 changes: 21 additions & 8 deletions aos/DisposeResources.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ var $then = callBound('Promise.prototype.then', true);

var CompletionRecord = require('es-abstract/2025/CompletionRecord');
var Dispose = require('./Dispose');
var NormalCompletion = require('es-abstract/2025/NormalCompletion');
var PromiseResolve = require('es-abstract/2025/PromiseResolve');
var ThrowCompletion = require('es-abstract/2025/ThrowCompletion');

Expand Down Expand Up @@ -56,9 +55,8 @@ module.exports = function DisposeResources(disposeCapability, completion) {
};

var getPromise = actualHint === 'ASYNC-DISPOSE' && function getPromise(resource) {
return $then(
promise,
function () {
var runDispose = function () {
try {
var result = Dispose( // step 2.a
resource['[[ResourceValue]]'],
resource['[[Hint]]'],
Expand All @@ -67,9 +65,19 @@ module.exports = function DisposeResources(disposeCapability, completion) {
if (!result) {
throw new $SyntaxError('Assertion failed: non-`~ASYNC-DISPOSE~` resource returned a promise from Dispose');
}
return $then(result, NormalCompletion);
},
rejecter
return $then(result, void undefined, rejecter);
} catch (e) {
rejecter(e);
}
return void undefined;
};
return $then(
promise,
runDispose,
function (e) {
rejecter(e);
return runDispose();
}
);
};

Expand All @@ -96,5 +104,10 @@ module.exports = function DisposeResources(disposeCapability, completion) {
// eslint-disable-next-line no-param-reassign
disposeCapability['[[DisposableResourceStack]]'] = null; // step 3

return actualHint === 'ASYNC-DISPOSE' ? promise : completion; // step 4
if (actualHint === 'ASYNC-DISPOSE') { // step 4
return $then(promise, function () {
return completion;
});
}
return completion;
};
37 changes: 36 additions & 1 deletion test/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ var semver = require('semver');
var gOPD = require('gopd');
var defineAccessorProperty = require('define-accessor-property');
var SuppressedError = require('suppressed-error/polyfill')();
var SLOT = require('internal-slot');

var brokenNodePolyfill = semver.satisfies(process.version, '^18.18 || >= 20.4');

Expand Down Expand Up @@ -99,6 +100,12 @@ module.exports = {
instance.use();
instance.use(disposable);

// AddDisposableResource step 1.a: `use(null)` and `use(undefined)` on a sync stack must return without pushing a resource.
if (SLOT.has(instance, '[[DisposeCapability]]')) {
var cap = SLOT.get(instance, '[[DisposeCapability]]');
st.equal(cap['[[DisposableResourceStack]]'].length, 2, '`use(null)` and `use(undefined)` do not add a resource');
}

forEach(v.nonNullPrimitives, function (nonNullishObject) {
st['throws'](
function () { instance.use(nonNullishObject); },
Expand Down Expand Up @@ -614,7 +621,35 @@ module.exports = {
function (e) {
st.equal(e, throwSentinel, 'throws `throwSentinel`');
}
);
).then(function () {
// https://github.com/es-shims/DisposableStack/issues/9
var instance3 = new AsyncDisposableStack();
var ran = 0;
instance3.defer(function () { ran += 1; });
instance3.defer(throwsSentinel);

return instance3.disposeAsync().then(
function () {
st.fail('dispose with a throwing later disposable failed to throw');
},
function (e) {
st.equal(e, throwSentinel, 'throws `throwSentinel` when an earlier-pushed defer throws');
st.equal(ran, 1, 'later-pushed non-throwing defer still ran');
}
);
}).then(function () {
var instance4 = new AsyncDisposableStack();
instance4.defer(function () { return Promise.reject(throwSentinel); });

return instance4.disposeAsync().then(
function () {
st.fail('dispose with a rejecting disposable failed to throw');
},
function (e) {
st.equal(e, throwSentinel, 'rejecting defer surfaces `throwSentinel`');
}
);
});
});
});

Expand Down
Loading