Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

618
Visualizações
How to get catch after retryWhen?

I want to retry get request a few times with a second delay in case of error, but if all attemps failed, then execute error handler.

Following code retryes request, but catch is never executed. How can I fix it?

import {Response, Http} from '@angular/http';
import {Observable} from 'rxjs/Rx';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
this.http.get("/api/getData").map(data => {
  console.log('get')
  return data.json()
})
.retryWhen(err => {
  console.log('retry')
  return err.delay(1000).take(5)
})
.catch(err => {
  console.log('catch')
  this.handleHttpError(err)
  return err
})
.subscribe(data => {
  console.log('subscribe')
  console.log(data)
})
about 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

The problem here is that when the notification Observable returned from the callback in retryWhen sends the complete notification it's propagated further as complete which is not what you want from your description.

You want to send it as error notification which means you can't use take() and use some other operator to rethrow the error.

For example like this:

Observable.defer(() => Observable.throw("It's broken"))
  .retryWhen(err => {
    console.log('retry');
    let retries = 0;
    return err
      .delay(1000)
      .map(error => {
        if (retries++ === 5) {
          throw error;
        }
        return error;
      });
  })
  .catch(err => {
    console.log('catch');
    return Observable.of(err);
  })
  .subscribe(data => {
    console.log('subscribe');
    console.log(data);
  });

You can count the number of retries in the retries variable yourself and if it reaches some limit just rethrow the error. The map() operator wraps all callbacks with try-catch blocks so any error thrown in its callable is going to be sent as error signal.

about 4 years ago · Santiago Trujillo Relatório

0

return err.delay(1000).take(5)

There should be a error after retries, for example:

return err.delay(1000).take(5).concat(Observable.throw(err))

Thanks @martin for pointing out that this code actually throws Observable instead of error.

about 4 years ago · Santiago Trujillo Relatório

0

Using modern rxjs with pipe, pipe the observable you're returning in the retryWhen operator with some logic that will throw an error if a certain condition is met.

https://stackblitz.com/edit/rxjs-retrywhen-to-catch

import { interval, of, throwError, timer } from 'rxjs'; 
import { catchError, mergeMap, switchMap, retryWhen, tap } from 'rxjs/operators';

const source = interval(1000);

const example = source.pipe(
  // simulate error
  switchMap(count => count > 3
    // this will be caught by retryWhen
    ? throwError('Error from source!')
    : of(count)
  ),
  retryWhen(err$ => err$.pipe(
    // display error from source
    tap(console.error),
    // i === index, AKA how many tries
    mergeMap((err, i) => i > 1
      // throw error, which is caught by catchError
      // or second argument to subscribe function if catchError not used
      ? throwError('Error from retry!')
      // wait specified duration before retrying
      : timer(3000)
    )
  )),
  catchError(err => of('There was an error, but we handled it. 😉'))
);

example.subscribe(
  console.log,
  () => console.error('Nothing reaches this error handler because we used catchError')
);

/*

RESULT
0
1
2
3
Error from source!
0
1
2
3
Error from source!
0
1
2
3
Error from source!
There was an error, but we handled it. 😉

*/

Inspired by this solution from learn-rxjs

about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda