Остановить трубу посередине
В моем приложении angular у меня есть перехватчик обновления токена, который перехватывает 401-несанкционированные ошибки, пытается обновить токен доступа и снова выполняет исходный HTTP-запрос.
В некоторых случаях конечная точка обновления токена также может дать сбой и вернуть известную ошибку (в моем случае это ошибка 400 invalid_grant).
Часть перехватчика, обновляющая токен:
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
})
);
Когда это происходит, он переходит к оператору catchError, который выполняет 2 вещи: выходит из системы (с перенаправлением на страницу входа) и возвращает throwError (ошибка), эта ошибка, которую он выдает, является ошибкой 400-Invalid_grant.
Это приводит к тому, что новая ошибка поступает в некоторые операторы catchError в функциях, которые изначально запускали токен обновления.
Просто для контекста: я регистрирую ошибки в блоках catch и хочу избежать записи таких ошибок, потому что они обычно означают только то, что токен пользователя истек.
Я бы хотел как-то остановить эту цепочку операторов и просто перенаправить на страницу входа.
Возможно ли остановить канал посередине и избежать попадания как внешней catchError, так и следующего оператора в канале?
Ответы
Вы можете вернуть пустое значение, Observable
чтобы предотвратить попадание событий или ошибок в компонент, который будет уничтожен:
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;
})
);
Если я правильно понял вопрос, возможно, вам поможет оператор takeUntil . Пример будет выглядеть так:
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();
...
}
)
}
}