Skip to content

Commit

Permalink
Merge pull request #131 from MattiasBuelens/fix-bluebird-warnings
Browse files Browse the repository at this point in the history
Prevent Bluebird warning about a promise not being returned from a handler
  • Loading branch information
MattiasBuelens authored Jan 3, 2024
2 parents 5bf2685 + ebcce01 commit 5f232af
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 29 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* This allows TypeScript users to use new methods such as `ReadableStream.prototype[Symbol.asyncIterator]()`,
even when TypeScript doesn't yet have a built-in type definition for them.
* 💥 The type definitions now require TypeScript 3.5 or higher. ([#130](https://github.com/MattiasBuelens/web-streams-polyfill/pull/130))
* 🐛 Prevent [warnings from Bluebird](http://bluebirdjs.com/docs/warning-explanations.html#warning-a-promise-was-created-in-a-handler-but-was-not-returned-from-it) about a promise being created within a handler but not being returned from a handler. ([#131](https://github.com/MattiasBuelens/web-streams-polyfill/pull/131))

## v3.2.1 (2022-04-07)

Expand Down
11 changes: 7 additions & 4 deletions src/lib/helpers/webidl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,25 @@ export function PerformPromiseThen<T, TResult1 = T, TResult2 = never>(
return originalPromiseThen.call(promise, onFulfilled, onRejected) as Promise<TResult1 | TResult2>;
}

// Bluebird logs a warning when a promise is created within a fulfillment handler, but then isn't returned
// from that handler. To prevent this, return null instead of void from all handlers.
// http://bluebirdjs.com/docs/warning-explanations.html#warning-a-promise-was-created-in-a-handler-but-was-not-returned-from-it
export function uponPromise<T>(
promise: Promise<T>,
onFulfilled?: (value: T) => void | PromiseLike<void>,
onRejected?: (reason: any) => void | PromiseLike<void>): void {
onFulfilled?: (value: T) => null | PromiseLike<null>,
onRejected?: (reason: any) => null | PromiseLike<null>): void {
PerformPromiseThen(
PerformPromiseThen(promise, onFulfilled, onRejected),
undefined,
rethrowAssertionErrorRejection
);
}

export function uponFulfillment<T>(promise: Promise<T>, onFulfilled: (value: T) => void | PromiseLike<void>): void {
export function uponFulfillment<T>(promise: Promise<T>, onFulfilled: (value: T) => null | PromiseLike<null>): void {
uponPromise(promise, onFulfilled);
}

export function uponRejection(promise: Promise<unknown>, onRejected: (reason: any) => void | PromiseLike<void>): void {
export function uponRejection(promise: Promise<unknown>, onRejected: (reason: any) => null | PromiseLike<null>): void {
uponPromise(promise, undefined, onRejected);
}

Expand Down
17 changes: 14 additions & 3 deletions src/lib/readable-stream/byte-stream-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,9 +426,12 @@ function ReadableByteStreamControllerCallPullIfNeeded(controller: ReadableByteSt
controller._pullAgain = false;
ReadableByteStreamControllerCallPullIfNeeded(controller);
}

return null;
},
e => {
ReadableByteStreamControllerError(controller, e);
return null;
}
);
}
Expand Down Expand Up @@ -990,9 +993,11 @@ export function SetUpReadableByteStreamController(stream: ReadableByteStream,
assert(!controller._pullAgain);

ReadableByteStreamControllerCallPullIfNeeded(controller);
return null;
},
r => {
ReadableByteStreamControllerError(controller, r);
return null;
}
);
}
Expand All @@ -1004,18 +1009,24 @@ export function SetUpReadableByteStreamControllerFromUnderlyingSource(
) {
const controller: ReadableByteStreamController = Object.create(ReadableByteStreamController.prototype);

let startAlgorithm: () => void | PromiseLike<void> = () => undefined;
let pullAlgorithm: () => Promise<void> = () => promiseResolvedWith(undefined);
let cancelAlgorithm: (reason: any) => Promise<void> = () => promiseResolvedWith(undefined);
let startAlgorithm: () => void | PromiseLike<void>;
let pullAlgorithm: () => Promise<void>;
let cancelAlgorithm: (reason: any) => Promise<void>;

if (underlyingByteSource.start !== undefined) {
startAlgorithm = () => underlyingByteSource.start!(controller);
} else {
startAlgorithm = () => undefined;
}
if (underlyingByteSource.pull !== undefined) {
pullAlgorithm = () => underlyingByteSource.pull!(controller);
} else {
pullAlgorithm = () => promiseResolvedWith(undefined);
}
if (underlyingByteSource.cancel !== undefined) {
cancelAlgorithm = reason => underlyingByteSource.cancel!(reason);
} else {
cancelAlgorithm = () => promiseResolvedWith(undefined);
}

const autoAllocateChunkSize = underlyingByteSource.autoAllocateChunkSize;
Expand Down
17 changes: 14 additions & 3 deletions src/lib/readable-stream/default-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,9 +187,12 @@ function ReadableStreamDefaultControllerCallPullIfNeeded(controller: ReadableStr
controller._pullAgain = false;
ReadableStreamDefaultControllerCallPullIfNeeded(controller);
}

return null;
},
e => {
ReadableStreamDefaultControllerError(controller, e);
return null;
}
);
}
Expand Down Expand Up @@ -362,9 +365,11 @@ export function SetUpReadableStreamDefaultController<R>(stream: ReadableStream<R
assert(!controller._pullAgain);

ReadableStreamDefaultControllerCallPullIfNeeded(controller);
return null;
},
r => {
ReadableStreamDefaultControllerError(controller, r);
return null;
}
);
}
Expand All @@ -377,18 +382,24 @@ export function SetUpReadableStreamDefaultControllerFromUnderlyingSource<R>(
) {
const controller: ReadableStreamDefaultController<R> = Object.create(ReadableStreamDefaultController.prototype);

let startAlgorithm: () => void | PromiseLike<void> = () => undefined;
let pullAlgorithm: () => Promise<void> = () => promiseResolvedWith(undefined);
let cancelAlgorithm: (reason: any) => Promise<void> = () => promiseResolvedWith(undefined);
let startAlgorithm: () => void | PromiseLike<void>;
let pullAlgorithm: () => Promise<void>;
let cancelAlgorithm: (reason: any) => Promise<void>;

if (underlyingSource.start !== undefined) {
startAlgorithm = () => underlyingSource.start!(controller);
} else {
startAlgorithm = () => undefined;
}
if (underlyingSource.pull !== undefined) {
pullAlgorithm = () => underlyingSource.pull!(controller);
} else {
pullAlgorithm = () => promiseResolvedWith(undefined);
}
if (underlyingSource.cancel !== undefined) {
cancelAlgorithm = reason => underlyingSource.cancel!(reason);
} else {
cancelAlgorithm = () => promiseResolvedWith(undefined);
}

SetUpReadableStreamDefaultController(
Expand Down
14 changes: 10 additions & 4 deletions src/lib/readable-stream/pipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export function ReadableStreamPipeTo<T>(source: ReadableStream<T>,
} else {
shutdown(true, storedError);
}
return null;
});

// Errors must be propagated backward
Expand All @@ -141,6 +142,7 @@ export function ReadableStreamPipeTo<T>(source: ReadableStream<T>,
} else {
shutdown(true, storedError);
}
return null;
});

// Closing must be propagated forward
Expand All @@ -150,6 +152,7 @@ export function ReadableStreamPipeTo<T>(source: ReadableStream<T>,
} else {
shutdown();
}
return null;
});

// Closing must be propagated backward
Expand Down Expand Up @@ -177,15 +180,15 @@ export function ReadableStreamPipeTo<T>(source: ReadableStream<T>,

function isOrBecomesErrored(stream: ReadableStream | WritableStream,
promise: Promise<void>,
action: (reason: any) => void) {
action: (reason: any) => null) {
if (stream._state === 'errored') {
action(stream._storedError);
} else {
uponRejection(promise, action);
}
}

function isOrBecomesClosed(stream: ReadableStream | WritableStream, promise: Promise<void>, action: () => void) {
function isOrBecomesClosed(stream: ReadableStream | WritableStream, promise: Promise<void>, action: () => null) {
if (stream._state === 'closed') {
action();
} else {
Expand All @@ -205,12 +208,13 @@ export function ReadableStreamPipeTo<T>(source: ReadableStream<T>,
doTheRest();
}

function doTheRest() {
function doTheRest(): null {
uponPromise(
action(),
() => finalize(originalIsError, originalError),
newError => finalize(true, newError)
);
return null;
}
}

Expand All @@ -227,7 +231,7 @@ export function ReadableStreamPipeTo<T>(source: ReadableStream<T>,
}
}

function finalize(isError?: boolean, error?: any) {
function finalize(isError?: boolean, error?: any): null {
WritableStreamDefaultWriterRelease(writer);
ReadableStreamReaderGenericRelease(reader);

Expand All @@ -239,6 +243,8 @@ export function ReadableStreamPipeTo<T>(source: ReadableStream<T>,
} else {
resolve(undefined);
}

return null;
}
});
}
4 changes: 3 additions & 1 deletion src/lib/readable-stream/tee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ export function ReadableStreamDefaultTee<R>(stream: ReadableStream<R>,
if (!canceled1 || !canceled2) {
resolveCancelPromise(undefined);
}
return null;
});

return [branch1, branch2];
Expand Down Expand Up @@ -200,13 +201,14 @@ export function ReadableByteStreamTee(stream: ReadableByteStream): [ReadableByte
function forwardReaderError(thisReader: ReadableStreamReader<Uint8Array>) {
uponRejection(thisReader._closedPromise, r => {
if (thisReader !== reader) {
return;
return null;
}
ReadableByteStreamControllerError(branch1._readableStreamController, r);
ReadableByteStreamControllerError(branch2._readableStreamController, r);
if (!canceled1 || !canceled2) {
resolveCancelPromise(undefined);
}
return null;
});
}

Expand Down
24 changes: 14 additions & 10 deletions src/lib/transform-stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,22 +374,26 @@ function SetUpTransformStreamDefaultControllerFromTransformer<I, O>(stream: Tran
transformer: ValidatedTransformer<I, O>) {
const controller: TransformStreamDefaultController<O> = Object.create(TransformStreamDefaultController.prototype);

let transformAlgorithm = (chunk: I): Promise<void> => {
try {
TransformStreamDefaultControllerEnqueue(controller, chunk as unknown as O);
return promiseResolvedWith(undefined);
} catch (transformResultE) {
return promiseRejectedWith(transformResultE);
}
};

let flushAlgorithm: () => Promise<void> = () => promiseResolvedWith(undefined);
let transformAlgorithm: (chunk: I) => Promise<void>;
let flushAlgorithm: () => Promise<void>;

if (transformer.transform !== undefined) {
transformAlgorithm = chunk => transformer.transform!(chunk, controller);
} else {
transformAlgorithm = chunk => {
try {
TransformStreamDefaultControllerEnqueue(controller, chunk as unknown as O);
return promiseResolvedWith(undefined);
} catch (transformResultE) {
return promiseRejectedWith(transformResultE);
}
};
}

if (transformer.flush !== undefined) {
flushAlgorithm = () => transformer.flush!(controller);
} else {
flushAlgorithm = () => promiseResolvedWith(undefined);
}

SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm);
Expand Down
24 changes: 20 additions & 4 deletions src/lib/writable-stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -453,10 +453,12 @@ function WritableStreamFinishErroring(stream: WritableStream) {
() => {
abortRequest._resolve();
WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
return null;
},
(reason: any) => {
abortRequest._reject(reason);
WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
return null;
});
}

Expand Down Expand Up @@ -1097,11 +1099,13 @@ function SetUpWritableStreamDefaultController<W>(stream: WritableStream<W>,
assert(stream._state === 'writable' || stream._state === 'erroring');
controller._started = true;
WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
return null;
},
r => {
assert(stream._state === 'writable' || stream._state === 'erroring');
controller._started = true;
WritableStreamDealWithRejection(stream, r);
return null;
}
);
}
Expand All @@ -1112,22 +1116,30 @@ function SetUpWritableStreamDefaultControllerFromUnderlyingSink<W>(stream: Writa
sizeAlgorithm: QueuingStrategySizeCallback<W>) {
const controller = Object.create(WritableStreamDefaultController.prototype);

let startAlgorithm: () => void | PromiseLike<void> = () => undefined;
let writeAlgorithm: (chunk: W) => Promise<void> = () => promiseResolvedWith(undefined);
let closeAlgorithm: () => Promise<void> = () => promiseResolvedWith(undefined);
let abortAlgorithm: (reason: any) => Promise<void> = () => promiseResolvedWith(undefined);
let startAlgorithm: () => void | PromiseLike<void>;
let writeAlgorithm: (chunk: W) => Promise<void>;
let closeAlgorithm: () => Promise<void>;
let abortAlgorithm: (reason: any) => Promise<void>;

if (underlyingSink.start !== undefined) {
startAlgorithm = () => underlyingSink.start!(controller);
} else {
startAlgorithm = () => undefined;
}
if (underlyingSink.write !== undefined) {
writeAlgorithm = chunk => underlyingSink.write!(chunk, controller);
} else {
writeAlgorithm = () => promiseResolvedWith(undefined);
}
if (underlyingSink.close !== undefined) {
closeAlgorithm = () => underlyingSink.close!();
} else {
closeAlgorithm = () => promiseResolvedWith(undefined);
}
if (underlyingSink.abort !== undefined) {
abortAlgorithm = reason => underlyingSink.abort!(reason);
} else {
abortAlgorithm = () => promiseResolvedWith(undefined);
}

SetUpWritableStreamDefaultController(
Expand Down Expand Up @@ -1233,9 +1245,11 @@ function WritableStreamDefaultControllerProcessClose(controller: WritableStreamD
sinkClosePromise,
() => {
WritableStreamFinishInFlightClose(stream);
return null;
},
reason => {
WritableStreamFinishInFlightCloseWithError(stream, reason);
return null;
}
);
}
Expand All @@ -1262,12 +1276,14 @@ function WritableStreamDefaultControllerProcessWrite<W>(controller: WritableStre
}

WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller);
return null;
},
reason => {
if (stream._state === 'writable') {
WritableStreamDefaultControllerClearAlgorithms(controller);
}
WritableStreamFinishInFlightWriteWithError(stream, reason);
return null;
}
);
}
Expand Down

0 comments on commit 5f232af

Please sign in to comment.