Skip to content

Catch() and its shared subscriptions #763

Closed
@staltz

Description

@staltz

When writing tests for catch(), I noticed this behavior:

  it('should catch and allow the cold observable to be repeated with the third ' +
  '(caught) argument', function () {
    var e1 =  cold('--a--b--c--------|       ');
    var subs =    ['^                       !',
                   '        ^               !',
                   '                ^       !'];
    var expected = '--a--b----a--b----a--b--#';

    var retries = 0;
    var result = e1
      .map(function (n) {
        if (n === 'c') {
          throw 'bad';
        }
        return n;
      })
      .catch(function (err, caught) {
        if (retries++ === 2) {
          throw 'done';
        }
        return caught;
      });

    expectObservable(result).toBe(expected, undefined, 'done');
    expectSubscriptions(e1.subscriptions).toBe(subs);
  });

Special attention given to this part:

    var e1 =  cold('--a--b--c--------|       ');
    var subs =    ['^                       !',
                   '        ^               !',
                   '                ^       !'];

This happens because CatchSubscriber does

  _error(err) {
    const result = tryCatch(this.selector)(err, this.caught);
    if (result === errorObject) {
      this.destination.error(errorObject.e);
    } else {
      this.add(result.subscribe(this.destination)); // <====
    }
  }

As a consequence, if someone uses source.catch(e => source) as a flavor of retry(), the number of subscriptions will indefinitely grow and stay retained.

What do you think should be done about this behavior?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions