Cómo lanzar error desde el operador de mapa RxJS (angular)


Quiero lanzar un error del operador de mi observable map basado en una condición. Por ejemplo, si no se reciben los datos API correctos. Véase el siguiente código:

private userAuthenticate( email: string, password: string ) {
    return this.httpPost(`${this.baseApiUrl}/auth?format=json&provider=login`, {userName: email, password: password})
        .map( res => { 
            if ( res.bearerToken ) {
                return this.saveJwt(res.bearerToken); 
            } else {
                // THIS DOESN'T THROW ERROR --------------------
                return Observable.throw('Valid token not returned');
            }
        })
        .catch( err => Observable.throw(this.logError(err) )
        .finally( () => console.log("Authentication done.") );
}

Básicamente, como se puede ver en el código, si la respuesta (objeto res) no tiene 'bearerToken' quiero lanzar un error. De modo que en mi suscripción entra en el segundo parámetro (HandleError) mencionado a continuación.

.subscribe(success, handleError)

Alguna sugerencia?

Author: Hassan, 2017-04-04

2 answers

Simplemente arroja el error dentro del operador .map(). Todas las devoluciones de llamada en RxJS están envueltas con bloques try-catch, por lo que se capturarán y luego se enviarán como una notificación error.

Esto significa que no devuelves nada y simplemente lanzas el error:

.map(res => { 
  if (res.bearerToken) {
    return this.saveJwt(res.bearerToken); 
  } else {
    throw new Error('Valid token not returned');
  }
})

El Observable.throw() es un Observable que solo envía una notificación error pero a map() no le importa lo que devuelvas. Incluso si devuelve un Observable desde map() se pasará como señal next.

Lo último, probablemente no necesita para usar .catch(). Si necesita realizar algún efecto secundario cuando ocurre un error, es mejor usar do(null, err => console.log(err)) por ejemplo.

 47
Author: martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-28 09:46:01

Prueba esto

Observable.throw(new Error('error!'));
 -1
Author: David,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-04 06:24:27