Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent Bluebird warning about a promise not being returned from a handler #131

Merged
merged 3 commits into from
Jan 3, 2024
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
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
Loading