es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

RxJS – Uso condicional del operador RetryWhen

Me gustaría idear una estrategia de manejo de errores escalable para mis solicitudes basadas en Observable de Firebase. Para hacerlo, estoy tratando de crear un operador RxJS personalizado para cada tipo de error (por ejemplo, no autenticado, interno, etc.). Los operadores se apilarían después de la solicitud de la siguiente manera:


FirebaseRequestObservable.pipe(
...
handleUnauthenticatedError(),
handleInternalError(),
handleYouNameItError(),
...
)

Esto funciona bien si mis operadores de manejo de errores solo se constituyen de un operador catchError, en cuyo caso su estructura interna puede ser simplemente:
“`
source.pipe(
catchError((err) => {
if (err !== errorThisOperatorShouldHandle) {
throw err
}
handleError
}
))</p>

“`
Para que el error se filtre hasta el siguiente operador personalizado si no debe ser manejado por ese operador.

El problema surge cuando mi lógica de manejo de errores para cierto error involucra el uso de retryWhen. No sé cómo podría entonces hacer que el operador emplee condicionalmente retryWhen si es el error correcto, y volver a arrojar el error al siguiente operador si no lo es.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Como experto en IT especializado en RxJS y los operadores RxJS-pipeable, recomendaría implementar una estrategia de manejo de errores unificada en lugar de crear un operador personalizado para cada tipo de error. Esto simplificará la lógica de manejo de errores y la hará más escalable.

    Puede lograr esto creando un solo operador de manejo de errores que pueda manejar todos los tipos de errores. Dentro de este operador, puede usar el operador catchError para capturar cualquier error y switchMap para manejar cada tipo de error individualmente. Si el error no es uno que el operador esté diseñado para manejar, se puede volver a lanzar para que el siguiente operador lo maneje.

    Por ejemplo:

    function handleErrors() {
      return (source) => source.pipe(
        catchError((err) => {
          return of(err).pipe(
            switchMap(error => {
              if (error.type === 'unauthenticated') {
                return handleUnauthenticatedError()
              } else if (error.type === 'internal') {
                return handleInternalError().pipe(
                  retryWhen(errors => errors.pipe(
                    delay(1000),
                    take(3)
                  ))
                )
              } else if (error.type === 'youNameIt') {
                return handleYouNameItError()
              } else {
                throw err;
              }
            })
          )
        })
      )
    }
    

    En este ejemplo, la función handleErrors devuelve una nueva función que toma el observable source como entrada. El operador comienza con el operador catchError para capturar cualquier error. Dentro del operador catchError, usamos el operador switchMap para manejar cada tipo de error individualmente.

    Para el tipo de error interno, primero llamamos a la función handleInternalError y luego usamos el operador retryWhen para volver a intentar automáticamente la solicitud en caso de errores transitorios.

    Si el error no es uno que el operador esté diseñado para manejar, simplemente volvemos a lanzar el error al siguiente operador para que lo maneje.

    Por último, puede aplicar este operador a su observable de solicitud de Firebase de la siguiente manera:

    FirebaseRequestObservable.pipe(
      ...
      handleErrors(),
      ...
    )
    

    Este enfoque le permitirá manejar todos los tipos de errores de manera unificada y escalable, y facilita la adición de nuevos tipos de errores en el futuro.

Comments are closed.