Reputation: 4360
Based on this question Angular intercepting http errors that is resolved, I'm facing a huge philosophical issue.
All my services look like this:
public getSomething(): Observable<Something> {
return this.http
.get<Something>(url)
.pipe(
map(res => res.data),
catchError((e): Observable<any> => of(e))
);
}
If my authentication token is invalid / expired, the service catches the error. I can call log out right there.
However, if I have a lot of services, I have to repeat this process that many times. Thus I need to configure an interceptor or a custom error handler.
Both are not triggered if I keep catchError in the services.
If I choose to stay DRY, I need to remove catchError. If I remove catchError, rxjs becomes practically useless (finalize, retry...etc.)
If I choose to keep catchError, I need to modify all of them to call some kind of global error handling function to stay somewhat DRY. But then I'm not using Angular like I should.
How do I handle this situation?
EDIT: https://stackblitz.com/edit/angular-m2jc9n
There's the ErrorHandler active, the Interceptor is commented in app.module. If you remove catchError from the service, the ErrorHandler is triggered, otherwise catchError takes precedence.
Upvotes: 0
Views: 270
Reputation: 6821
If you want to have a shared interceptor, you have in angular the HTTP_INTERCEPTOR:
in your module.ts
@NgModule({
declarations: [
...
],
imports: [
...
],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: LoginInterceptor,
multi: true
}
]
})
And the service LoginInterceptor
:
@Injectable()
export class LoginInterceptor implements HttpInterceptor {
constructor() {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
tap(() => {
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
// DO here what you want
// this.router.navigate(['login']);
}
}
)
);
}
}
An alternative will be to use a guard on the top of your route.
Upvotes: 1