BeetleJuice
BeetleJuice

Reputation: 40886

rxjs timeout: distinguish time expired from source error

Using RxJS 6.5, I subscribe to a stream and I'd like to take two distinct actions: - one when the source errors - another when the source takes too long to send data (timeout)

Here is what I currently have

source$.pipe(
  timeoutWith(5000, log('timeout!')),
  catchError(log('error!'))
).subscribe();

function log(msg) {
  console.log(msg);
  return of(null);
}

When my source takes longer than 5000ms to emit, I get the expected result: timeout!

However when my source throws an error early (before the 5000ms), both lines execute. It seems as though it timeoutWith is triggered whenever the source did not emit, even if it errored.

How can I set up a pipe so that the timeout logic only runs if time has actually elapsed, not because the stream was aborted due to an error?

Playground

Upvotes: 0

Views: 677

Answers (1)

benshabatnoam
benshabatnoam

Reputation: 7632

It looks like your correct operator to use is timeout instead of timeoutWith and I'll explain.

timeoutWith will - Subscribe to second Observable if no emission occurs in given time span. and this is not your needs.

timeout will - Error if no value is emitted before specified duration which is best for your needs/

Using timeout in your pipe should look like this:

source$.pipe(
  catchError(() => log('func error!')), // will log only when your source throws an error
  timeout(5000),
  catchError(() => log('timeout error!')) // will log only if your source as timed-out for 5000
).subscribe();

StackBlitz DEMO

Upvotes: 1

Related Questions