Skip to content

Commit acd8fbd

Browse files
committed
fix: ensure catchError functions always return source iterator
1 parent b8890f1 commit acd8fbd

File tree

6 files changed

+67
-58
lines changed

6 files changed

+67
-58
lines changed

docs/asynciterable/creating.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ let value, done;
4646

4747
## Brief Interlude - `AsyncSink`
4848

49-
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.
49+
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.
5050

5151
```typescript
5252
import { AsyncSink } from 'ix/asynciterable';

docs/asynciterable/transforming.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,5 @@ await subscription.pipe(
1111
.forEach(handleBatch)
1212
```
1313

14-
Using this operator makes sure that if messages slow down you'll still
15-
handle them in a reasonable time whereas using `buffer` would leave you stuck until you get
14+
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
1615
the right amount of messages.

src/asynciterable/catcherror.ts

+16-14
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,26 @@ export class CatchAllAsyncIterable<TSource> extends AsyncIterableX<TSource> {
2424
error = null;
2525
hasError = false;
2626

27-
while (1) {
28-
let c = <TSource>{};
27+
try {
28+
while (1) {
29+
let c = <TSource>{};
2930

30-
try {
31-
const { done, value } = await it.next();
32-
if (done) {
33-
await returnAsyncIterator(it);
31+
try {
32+
const { done, value } = await it.next();
33+
if (done) {
34+
break;
35+
}
36+
c = value;
37+
} catch (e) {
38+
error = e;
39+
hasError = true;
3440
break;
3541
}
36-
c = value;
37-
} catch (e) {
38-
error = e;
39-
hasError = true;
40-
await returnAsyncIterator(it);
41-
break;
42-
}
4342

44-
yield c;
43+
yield c;
44+
}
45+
} finally {
46+
await returnAsyncIterator(it);
4547
}
4648

4749
if (!hasError) {

src/asynciterable/operators/catcherror.ts

+16-13
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,26 @@ export class CatchWithAsyncIterable<TSource, TResult> extends AsyncIterableX<TSo
3030
let hasError = false;
3131
const source = wrapWithAbort(this._source, signal);
3232
const it = source[Symbol.asyncIterator]();
33-
while (1) {
34-
let c = <IteratorResult<TSource>>{};
3533

36-
try {
37-
c = await it.next();
38-
if (c.done) {
39-
await returnAsyncIterator(it);
34+
try {
35+
while (1) {
36+
let c = <IteratorResult<TSource>>{};
37+
38+
try {
39+
c = await it.next();
40+
if (c.done) {
41+
break;
42+
}
43+
} catch (e) {
44+
err = await this._handler(e, signal);
45+
hasError = true;
4046
break;
4147
}
42-
} catch (e) {
43-
err = await this._handler(e, signal);
44-
hasError = true;
45-
await returnAsyncIterator(it);
46-
break;
47-
}
4848

49-
yield c.value;
49+
yield c.value;
50+
}
51+
} finally {
52+
await returnAsyncIterator(it);
5053
}
5154

5255
if (hasError) {

src/iterable/catcherror.ts

+16-14
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,26 @@ export class CatchIterable<TSource> extends IterableX<TSource> {
2020
error = null;
2121
hasError = false;
2222

23-
while (1) {
24-
let c = <TSource>{};
23+
try {
24+
while (1) {
25+
let c = <TSource>{};
2526

26-
try {
27-
const { done, value } = it.next();
28-
if (done) {
29-
returnIterator(it);
27+
try {
28+
const { done, value } = it.next();
29+
if (done) {
30+
break;
31+
}
32+
c = value;
33+
} catch (e) {
34+
error = e;
35+
hasError = true;
3036
break;
3137
}
32-
c = value;
33-
} catch (e) {
34-
error = e;
35-
hasError = true;
36-
returnIterator(it);
37-
break;
38-
}
3938

40-
yield c;
39+
yield c;
40+
}
41+
} finally {
42+
returnIterator(it);
4143
}
4244

4345
if (!hasError) {

src/iterable/operators/catcherror.ts

+17-14
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,27 @@ export class CatchWithIterable<TSource, TResult> extends IterableX<TSource | TRe
1717
let err: Iterable<TResult> | undefined;
1818
let hasError = false;
1919
const it = this._source[Symbol.iterator]();
20-
while (1) {
21-
let done: boolean | undefined;
22-
let value: TSource;
2320

24-
try {
25-
({ done, value } = it.next());
26-
if (done) {
27-
returnIterator(it);
21+
try {
22+
while (1) {
23+
let done: boolean | undefined;
24+
let value: TSource;
25+
26+
try {
27+
({ done, value } = it.next());
28+
if (done) {
29+
break;
30+
}
31+
} catch (e) {
32+
err = this._handler(e);
33+
hasError = true;
2834
break;
2935
}
30-
} catch (e) {
31-
err = this._handler(e);
32-
hasError = true;
33-
returnIterator(it);
34-
break;
35-
}
3636

37-
yield value;
37+
yield value;
38+
}
39+
} finally {
40+
returnIterator(it);
3841
}
3942

4043
if (hasError) {

0 commit comments

Comments
 (0)