From acd8fbddf4e0b698b6ee1b9722579f6842466b42 Mon Sep 17 00:00:00 2001 From: Jesper Engberg Date: Fri, 19 Jul 2024 11:56:57 +0200 Subject: [PATCH] fix: ensure catchError functions always return source iterator --- docs/asynciterable/creating.md | 2 +- docs/asynciterable/transforming.md | 3 +-- src/asynciterable/catcherror.ts | 30 ++++++++++++---------- src/asynciterable/operators/catcherror.ts | 29 +++++++++++---------- src/iterable/catcherror.ts | 30 ++++++++++++---------- src/iterable/operators/catcherror.ts | 31 +++++++++++++---------- 6 files changed, 67 insertions(+), 58 deletions(-) diff --git a/docs/asynciterable/creating.md b/docs/asynciterable/creating.md index ba34cdf1..d2a1468b 100644 --- a/docs/asynciterable/creating.md +++ b/docs/asynciterable/creating.md @@ -46,7 +46,7 @@ let value, done; ## Brief Interlude - `AsyncSink` -Very rarely will we ever need to create these async-iterables by hand, however, if you need a collection that you can add to as well as iterate, we have the `AsyncSink` class. This class serves as a basis for some of our operators such as binding to events and DOM and Node.js streams. +Very rarely will we ever need to create these async-iterables by hand, however, if you need a collection that you can add to as well as iterate, we have the `AsyncSink` class. This class serves as a basis for some of our operators such as binding to events and DOM and Node.js streams. ```typescript import { AsyncSink } from 'ix/asynciterable'; diff --git a/docs/asynciterable/transforming.md b/docs/asynciterable/transforming.md index b249cba4..d8824bdf 100644 --- a/docs/asynciterable/transforming.md +++ b/docs/asynciterable/transforming.md @@ -11,6 +11,5 @@ await subscription.pipe( .forEach(handleBatch) ``` -Using this operator makes sure that if messages slow down you'll still -handle them in a reasonable time whereas using `buffer` would leave you stuck until you get +Using this operator makes sure that if messages slow down you'll still handle them in a reasonable time whereas using `buffer` would leave you stuck until you get the right amount of messages. diff --git a/src/asynciterable/catcherror.ts b/src/asynciterable/catcherror.ts index 90de1cc8..86c3dc93 100644 --- a/src/asynciterable/catcherror.ts +++ b/src/asynciterable/catcherror.ts @@ -24,24 +24,26 @@ export class CatchAllAsyncIterable extends AsyncIterableX { error = null; hasError = false; - while (1) { - let c = {}; + try { + while (1) { + let c = {}; - try { - const { done, value } = await it.next(); - if (done) { - await returnAsyncIterator(it); + try { + const { done, value } = await it.next(); + if (done) { + break; + } + c = value; + } catch (e) { + error = e; + hasError = true; break; } - c = value; - } catch (e) { - error = e; - hasError = true; - await returnAsyncIterator(it); - break; - } - yield c; + yield c; + } + } finally { + await returnAsyncIterator(it); } if (!hasError) { diff --git a/src/asynciterable/operators/catcherror.ts b/src/asynciterable/operators/catcherror.ts index 943cc83c..fb569010 100644 --- a/src/asynciterable/operators/catcherror.ts +++ b/src/asynciterable/operators/catcherror.ts @@ -30,23 +30,26 @@ export class CatchWithAsyncIterable extends AsyncIterableX>{}; - try { - c = await it.next(); - if (c.done) { - await returnAsyncIterator(it); + try { + while (1) { + let c = >{}; + + try { + c = await it.next(); + if (c.done) { + break; + } + } catch (e) { + err = await this._handler(e, signal); + hasError = true; break; } - } catch (e) { - err = await this._handler(e, signal); - hasError = true; - await returnAsyncIterator(it); - break; - } - yield c.value; + yield c.value; + } + } finally { + await returnAsyncIterator(it); } if (hasError) { diff --git a/src/iterable/catcherror.ts b/src/iterable/catcherror.ts index 827efbba..f43d5e60 100644 --- a/src/iterable/catcherror.ts +++ b/src/iterable/catcherror.ts @@ -20,24 +20,26 @@ export class CatchIterable extends IterableX { error = null; hasError = false; - while (1) { - let c = {}; + try { + while (1) { + let c = {}; - try { - const { done, value } = it.next(); - if (done) { - returnIterator(it); + try { + const { done, value } = it.next(); + if (done) { + break; + } + c = value; + } catch (e) { + error = e; + hasError = true; break; } - c = value; - } catch (e) { - error = e; - hasError = true; - returnIterator(it); - break; - } - yield c; + yield c; + } + } finally { + returnIterator(it); } if (!hasError) { diff --git a/src/iterable/operators/catcherror.ts b/src/iterable/operators/catcherror.ts index 3c2dd565..85873c56 100644 --- a/src/iterable/operators/catcherror.ts +++ b/src/iterable/operators/catcherror.ts @@ -17,24 +17,27 @@ export class CatchWithIterable extends IterableX | undefined; let hasError = false; const it = this._source[Symbol.iterator](); - while (1) { - let done: boolean | undefined; - let value: TSource; - try { - ({ done, value } = it.next()); - if (done) { - returnIterator(it); + try { + while (1) { + let done: boolean | undefined; + let value: TSource; + + try { + ({ done, value } = it.next()); + if (done) { + break; + } + } catch (e) { + err = this._handler(e); + hasError = true; break; } - } catch (e) { - err = this._handler(e); - hasError = true; - returnIterator(it); - break; - } - yield value; + yield value; + } + } finally { + returnIterator(it); } if (hasError) {