Skip to content

Commit

Permalink
fix(vow): when honors rejection handler
Browse files Browse the repository at this point in the history
  • Loading branch information
mhofman committed Jul 13, 2024
1 parent cc6a9e5 commit b656ada
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 9 deletions.
30 changes: 23 additions & 7 deletions packages/vow/src/when.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,10 @@ export const makeWhen = (
* @see {@link ../../README.md}
*
* @template T
* @template [TResult1=EUnwrap<T>]
* @template [TResult2=never]
* @param {T} specimenP value to unwrap
* @param {(value: EUnwrap<T>) => TResult1 | PromiseLike<TResult1>} [onFulfilled]
* @param {(reason: any) => TResult2 | PromiseLike<TResult2>} [onRejected]
* @returns {Promise<TResult1 | TResult2>}
* @returns {Promise<EUnwrap<T>>}
*/
const when = async (specimenP, onFulfilled, onRejected) => {
const unwrap = async specimenP => {
// Ensure we don't run until a subsequent turn.
await null;

Expand Down Expand Up @@ -63,10 +59,30 @@ export const makeWhen = (
}

const unwrapped = /** @type {EUnwrap<T>} */ (result);
return unwrapped;
};

/**
* Shorten `specimenP` until we achieve a final result.
*
* Does not survive upgrade (even if specimenP is a durable Vow).
*
* @see {@link ../../README.md}
*
* @template T
* @template [TResult1=EUnwrap<T>]
* @template [TResult2=never]
* @param {T} specimenP value to unwrap
* @param {(value: EUnwrap<T>) => TResult1 | PromiseLike<TResult1>} [onFulfilled]
* @param {(reason: any) => TResult2 | PromiseLike<TResult2>} [onRejected]
* @returns {Promise<TResult1 | TResult2>}
*/
const when = (specimenP, onFulfilled, onRejected) => {
const unwrapped = unwrap(specimenP);

// We've extracted the final result.
if (onFulfilled == null && onRejected == null) {
return /** @type {TResult1} */ (unwrapped);
return /** @type {Promise<TResult1>} */ (unwrapped);
}
return basicE.resolve(unwrapped).then(onFulfilled, onRejected);
};
Expand Down
23 changes: 21 additions & 2 deletions packages/vow/test/disconnect.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ test('retry on disconnection', async t => {
[2, 'disco', 'disco', 'sad'],
];

for await (const pattern of ['when', 'watch']) {
for await (const pattern of [
'when',
'when-with-handlers',
'watch',
'watch-with-handler',
]) {
t.log('testing', pattern);
for await (const [final, ...plan] of PLANS) {
t.log(`testing (plan=${plan}, ${pattern})`);
Expand All @@ -66,7 +71,7 @@ test('retry on disconnection', async t => {

let resultP;
switch (pattern) {
case 'watch': {
case 'watch-with-handler': {
const resultW = watch(vow, {
onFulfilled(value) {
t.is(plan[final], 'happy');
Expand All @@ -83,10 +88,24 @@ test('retry on disconnection', async t => {
resultP = when(resultW);
break;
}
case 'watch': {
const resultW = watch(vow);
t.is('then' in resultW, false, 'watch resultW.then is undefined');
resultP = when(resultW).catch(e => ['rejected', e]);
break;
}
case 'when': {
resultP = when(vow).catch(e => ['rejected', e]);
break;
}
case 'when-with-handlers': {
resultP = when(
vow,
v => v,
e => ['rejected', e],
);
break;
}
default: {
t.fail(`unknown pattern ${pattern}`);
}
Expand Down

0 comments on commit b656ada

Please sign in to comment.