Skip to content

Commit

Permalink
Merge pull request #91 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 committed Sep 17, 2021
2 parents e759147 + bb5b194 commit 6eb297f
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 29 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
> - 🏠 Internal
> - 💅 Polish
## Unreleased

* 🐛 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. ([#91](https://github.com/MattiasBuelens/web-streams-polyfill/pull/91))

## v4.0.0-beta.1 (2021-09-06)

* 💥 Rework the list of variants to have more modern defaults.
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 @@ -421,9 +421,12 @@ function ReadableByteStreamControllerCallPullIfNeeded(controller: ReadableByteSt
controller._pullAgain = false;
ReadableByteStreamControllerCallPullIfNeeded(controller);
}

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

ReadableByteStreamControllerCallPullIfNeeded(controller);
return null;
},
r => {
ReadableByteStreamControllerError(controller, r);
return null;
}
);
}
Expand All @@ -995,18 +1000,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 @@ -184,9 +184,12 @@ function ReadableStreamDefaultControllerCallPullIfNeeded(controller: ReadableStr
controller._pullAgain = false;
ReadableStreamDefaultControllerCallPullIfNeeded(controller);
}

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

ReadableStreamDefaultControllerCallPullIfNeeded(controller);
return null;
},
r => {
ReadableStreamDefaultControllerError(controller, r);
return null;
}
);
}
Expand All @@ -374,18 +379,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 @@ -166,6 +166,7 @@ export function ReadableStreamDefaultTee<R>(stream: ReadableStream<R>,
if (!canceled1 || !canceled2) {
resolveCancelPromise(undefined);
}
return null;
});

return [branch1, branch2];
Expand All @@ -192,13 +193,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 @@ -371,22 +371,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 @@ -447,10 +447,12 @@ function WritableStreamFinishErroring(stream: WritableStream) {
() => {
abortRequest._resolve();
WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
return null;
},
(reason: any) => {
abortRequest._reject(reason);
WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream);
return null;
});
}

Expand Down Expand Up @@ -1081,11 +1083,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 @@ -1096,22 +1100,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 @@ -1217,9 +1229,11 @@ function WritableStreamDefaultControllerProcessClose(controller: WritableStreamD
sinkClosePromise,
() => {
WritableStreamFinishInFlightClose(stream);
return null;
},
reason => {
WritableStreamFinishInFlightCloseWithError(stream, reason);
return null;
}
);
}
Expand All @@ -1246,12 +1260,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 6eb297f

Please sign in to comment.