Pare um cano no meio
Em meu aplicativo angular, tenho um interceptor de atualização de token que intercepta erros 401-Unauthorized, tenta atualizar um token de acesso e executa a solicitação http original novamente.
O endpoint de atualização de token também pode falhar em alguns casos e retornar um erro conhecido (no meu caso, é um erro 400 invalid_grant).
A parte do interceptor que atualiza o token:
return this.httpClient
.request('POST', "token", { observe: 'response' })
.pipe(
map(response => {
// some logic when the token was refreshed successfully
}),
catchError(err => {
this.routingService.navigateToLoginNoQuery();
return throwError(err); // a 400 - invalid_grant error
})
);
Quando isso acontece, ele chega a um operador catchError, que faz 2 coisas: logout (com redirecionamento para a página de login) e retorna throwError (erro), esse erro que ele lança é o erro 400-Invalid_grant.
Isso faz com que o novo erro chegue a alguns operadores catchError nas funções que originalmente acionaram o token de atualização.
Apenas para contexto: eu registro os erros nos blocos catch e quero evitar o registro desse tipo de erro, porque eles geralmente significam apenas que o token do usuário expirou.
O que eu gostaria de fazer é parar de alguma forma essa cadeia de operadores e apenas redirecionar para a página de login.
É possível parar um tubo no meio e evitar chegar a um catchError externo e ao próximo operador no tubo?
Respostas
Você pode retornar um vazio Observable
para evitar que eventos ou erros atinjam um componente que será destruído:
return this.httpClient
.request('POST', "token", { observe: 'response' })
.pipe(
map(response => {
// some logic when the token was refreshed successfully
}),
catchError(err => {
this.routingService.navigateToLoginNoQuery();
return EMPTY;
})
);
Se entendi a pergunta correta, talvez um operador takeUntil possa ajudá-lo. O exemplo ficará mais ou menos assim:
export class MyHttpInterceptor implements HttpInterceptor {
anyError = new Subject();
intercept(req: HttpRequest, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req)
.pipe(
takeUntil(this.anyError),
catchError(err => {
this.anyError.next();
...
}
)
}
}