Issue
I have the following code in an interceptor:
intercept(request: HttpRequest<any>, next: HttpHandler): any {
return next.handle(request).pipe(
catchError(async error => {
if (error instanceof HttpErrorResponse && (error.status === 302 || error.status === 401 || error.status === 403)) {
this.store.dispatch(new Authenticate());
try {
await firstValueFrom(this.store.pipe(
select(selectAuthCallState),
filter(state => state === ProcessState.COMPLETED),
take(1)
));
} catch (err) {
return throwError(async () => new Error(error.message));
}
}
return next.handle(request);
})
);
}
- When a HTTP request is getting a 401 error (for instance), it gets into the
catchError
block as expected. this.store.dispatch(new Authenticate());
is dispatching an authentication event, which works as expected.- Then, in order to detect the authentication completion, I'm awaiting the action to finish (by
await
ing the selector update) - works perfectly. - I'm then trying to recall the original request (which was rejected by the lack of authentication), and nothing happens.
What am I doing wrong?
Thanks!
Solution
Here's the solution I came up with. Should be switched to retry
instead of deprecated retryWhen
.
intercept(request: HttpRequest<any>, next: HttpHandler): any {
return next.handle(request).pipe(
retryWhen(errors => {
let count = 0;
return errors.pipe(
takeWhile(error =>
(error instanceof HttpErrorResponse && (error.status === 401 || error.status === 403) && ++count <= this.RETRY_COUNT)
),
concatMap(async (error) => {
this.store.dispatch(new Authenticate());
await firstValueFrom(this.store.pipe(
select(selectAuthCallState),
filter(state => state === ProcessState.COMPLETED),
take(1)));
return of(error);
})
);
})
);
}
Answered By - noamyg
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.