Issue
I have an app with some interceptors. I declared these in this order:
- loading interceptor
- auth interceptor
- database error interceptor
- global http error interceptor
If I f.e. want to delete a record, where there are some related records, the database error interceptor catches the error and gives a meaningful notification. Here is the code:
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError((error: HttpErrorResponse) => {
if (!(error.error instanceof ErrorEvent)) {
const httpError = error.error as CustomHttpErrorResponse;
if (httpError.message == 'Database error') {
const dbError = httpError as DatabaseError;
switch (dbError.details.code) {
case '23503':
this.notifyService.showNotification(
request.context.get(NOTIFICATION_TYPE).type,
5000,
'error',
'Törlés nem sikerült!',
`A törlés sajnos nem sikerült, mivel még vannak kapcsolódó objektumok (${this.getReferencedObjectName(
dbError.details.detail
)}).`,
request.context.get(NOTIFICATION_TYPE).container
);
break;
case '23505':
this.notifyService.showNotification(
request.context.get(NOTIFICATION_TYPE).type,
5000,
'error',
'Mentés nem sikerült!',
'A hozzáadni kívánt elem már létezik a listában.',
request.context.get(NOTIFICATION_TYPE).container
);
break;
}
}
}
return throwError(() => error);
})
);
}
After that it should stop the interceptor chain. But for some reason, I don't get the notification, instead I get the notification from the global http error interceptor.
Here is the code of the global http error interceptor:
intercept(
request: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError((error: HttpErrorResponse) => {
if (!(error.error instanceof ErrorEvent)) {
if (error.status != 401) {
this.notifyService.showNotification(
request.context.get(NOTIFICATION_TYPE).type,
5000,
'error',
'Hiba',
'Ismeretlen eredetű hiba lépett fel. Lépj kapcsolatba a rendszer adminisztrátorával.',
request.context.get(NOTIFICATION_TYPE).container
);
this.loaderService.hide();
return of();
}
}
return throwError(() => error);
})
);
}
First, I thought, this is because in the database error interceptor I rethrow the error and the next interceptor catches it. But if I simply return an empty observable like return of()
, the global http error interceptor is reached in this case too.
I checked it with console log (right after this line, before the if
: catchError((error: HttpErrorResponse) => {
), the database error interceptor is reached, but the catchError
codeblock not.
Why is that? What am'I overseeing?
Solution
The interceptor order works both ways.
The first interceptor transforms the request, then the 2nd, then the 3rd.
Then the response arrives and the last interceptor callback is first to run, then the 2nd-to-last etc.
This is why your global interceptor is the first to handle the response.
Answered By - Matthieu Riegler
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.