Skip to content

Commit 9ae9875

Browse files
wartabmmalerba
authored andcommitted
fix(core): Prevent an error on cleanup when an rxResource stream threw before returning an Observable (angular#63342)
Before this commit, it was wrongly assumed that the stream subscription could not be `undefined`. Fixes angular#63341 PR Close angular#63342
1 parent ec65663 commit 9ae9875

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

packages/core/rxjs-interop/src/rx_resource.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ export function rxResource<T, R>(opts: RxResourceOptions<T, R>): ResourceRef<T |
5555
...opts,
5656
loader: undefined,
5757
stream: (params) => {
58-
let sub: Subscription;
58+
let sub: Subscription | undefined;
5959

6060
// Track the abort listener so it can be removed if the Observable completes (as a memory
6161
// optimization).
62-
const onAbort = () => sub.unsubscribe();
62+
const onAbort = () => sub?.unsubscribe();
6363
params.abortSignal.addEventListener('abort', onAbort);
6464

6565
// Start off stream as undefined.

packages/core/rxjs-interop/test/rx_resource_spec.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ describe('rxResource()', () => {
7777
expect(res.error()).toEqual(jasmine.objectContaining({cause: 'fail'}));
7878
expect(res.error()!.message).toContain('Resource');
7979
});
80+
81+
it('should cleanup without error when the stream function threw an error', async () => {
82+
const appRef = TestBed.inject(ApplicationRef);
83+
const res = rxResource({
84+
stream: () => {
85+
throw 'oh no';
86+
},
87+
injector: appRef.injector,
88+
});
89+
await appRef.whenStable();
90+
});
8091
});
8192

8293
async function waitFor(fn: () => boolean): Promise<void> {

0 commit comments

Comments
 (0)