16

As expected, the following code emits 42 after 5 seconds:

const valueObservable = of(42).pipe(delay(5000));
valueObservable.subscribe((value) => console.log(value));

However, this throwing version errors immediately on subscription:

const throwingObservable = throwError(new Error('My Error')).pipe(delay(5000));
throwingObservable.subscribe((value) => console.log(value), (error) => console.error(error));

Why does this happen? How do I delay the throwing of the error?

Lukas Renggli
  • 8,754
  • 23
  • 46

3 Answers3

18

Rxjs error is exception, it stop immediately the stream and let you catch it to react to something un expected. I guess you have no way to manipulate throwError stream except with catchError

Solution 1: Manipulate stream before throw the error.

const throwingObservable = throwError(new Error('My Error'));
timer(5000).pipe(mergeMap(e => throwingObservable))
  .subscribe((value) => console.log(value), (error) => console.error(error));

Solution 2: Catch the error, delay the stream, then dispatch it again

throwingObservable.pipe(
  // We catch the error, we delay by adding timer stream, then we mergeMap to the error.
  catchError(e => timer(1000).pipe(mergeMap(t => throwError(e)))
)).subscribe(console.log, console.error);

You can see it in action

Yanis-git
  • 7,737
  • 3
  • 24
  • 41
6

I have found an (IMO) easier way of delaying the throwing of the error:

const throwingObservable = of(42).pipe(
    delay(5000),
    switchMap(() => throwError(() => new Error('My Error')))
);
throwingObservable.subscribe(
    value => console.log(value),
    error => console.error(error)
);
nsacerdote
  • 431
  • 5
  • 8
  • 1
    Nice - throwError used like that is deprecated now it needs to be like this fyi `throwError(() => new Error('My Error')))` – Joe Keene Jan 06 '23 at 12:52
4

I had a similar problem and found this github issue: https://github.com/Reactive-Extensions/RxJS/issues/648

Updated to my usecase it would be something like this:

const throwingObservable = throwError(new Error('My Error'))
  .pipe(
    materialize(),
    delay(4000),
    dematerialize()
  );

throwingObservable.subscribe(console.log, console.error);

It throws after a 4 seconds delay

Vee6
  • 1,527
  • 3
  • 21
  • 40