Skip to content

Commit 1a38c6f

Browse files
committed
fix: add error interceptor redirection mechanism
1 parent 763c411 commit 1a38c6f

File tree

1 file changed

+48
-2
lines changed

1 file changed

+48
-2
lines changed
Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,53 @@
1-
import { HttpInterceptorFn } from '@angular/common/http';
1+
import { HttpErrorResponse, HttpInterceptorFn } from '@angular/common/http';
2+
import { inject } from '@angular/core';
23
import { throwError } from 'rxjs';
34
import { catchError } from 'rxjs/operators';
5+
import { UserService } from '../auth/services/user.service';
46

7+
/**
8+
* Global HTTP error interceptor.
9+
*
10+
* ## 401 Handling Strategy
11+
*
12+
* There are two layers of 401 handling:
13+
*
14+
* 1. GET /user endpoint (auth initialization):
15+
* - Handled by UserService.getCurrentUser() with 4XX vs 5XX logic
16+
* - This interceptor SKIPS /user to avoid double-handling
17+
*
18+
* 2. All OTHER endpoints (articles, comments, profiles, etc.):
19+
* - Handled HERE - any 401 means "token expired mid-session"
20+
* - We call purgeAuth() to logout immediately
21+
*
22+
* Both paths result in logout on 401, but /user needs special handling
23+
* because it also distinguishes 5XX errors (server down → retry).
24+
*
25+
* ## Error Format
26+
*
27+
* Re-throws errors with { ...body, status } format so that:
28+
* - Components can access err.errors for display (e.g., validation errors)
29+
* - Auth logic can check err.status for error type decisions
30+
* - Network errors get a user-friendly fallback message
31+
*/
532
export const errorInterceptor: HttpInterceptorFn = (req, next) => {
6-
return next(req).pipe(catchError(err => throwError(() => err.error)));
33+
const userService = inject(UserService);
34+
35+
return next(req).pipe(
36+
catchError((err: HttpErrorResponse) => {
37+
// Global 401 handling for all endpoints EXCEPT /user
38+
// (token expired mid-session → logout)
39+
// /user is handled by UserService.getCurrentUser() with 4XX vs 5XX logic
40+
if (err.status === 401 && !req.url.endsWith('/user')) {
41+
userService.purgeAuth();
42+
}
43+
44+
// Normalize error format: { errors: {...}, status: number }
45+
// Provides fallback message for network errors (status 0) or missing body
46+
const body = err.error && typeof err.error === 'object' && 'errors' in err.error
47+
? err.error
48+
: { errors: { network: ['Unable to connect. Please check your internet connection.'] } };
49+
50+
return throwError(() => ({ ...body, status: err.status }));
51+
}),
52+
);
753
};

0 commit comments

Comments
 (0)