Skip to content

Commit 4081286

Browse files
committed
INT: refactored interceptors, now function interceptors also available
1 parent 56b02f1 commit 4081286

5 files changed

Lines changed: 216 additions & 28 deletions

File tree

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
### Features
66

7+
- new `httpGatewayTimeoutInterceptor` http interceptor function, which is used for intercepting http responses and handling 504 statuses
8+
- new `httpServerErrorInterceptor` http interceptor function, which is used for handling http server errors with codes 500..599 and displaying of internal server error
9+
- new `noConnectionInterceptor` http interceptor function, which is used for intercepting http responses and handling 0 statuses
10+
- new `serviceUnavailableInterceptor` http interceptor function, which is used for intercepting http responses and handling 503 statuses
711
- new `CatchHttpClientErrorHttpStatusCodeOptions` interface, which represents options for cattch http client errors specific for http status code
812
- **properties**
913
- `behavior` behavior of catch http client error, default is `CatchHttpClientErrorBehavior.Suppress`

src/httpInterceptors/httpGatewayTimeout/httpGatewayTimeout.interceptor.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import {Injectable, Optional, Injector, ClassProvider} from '@angular/core';
2-
import {HttpInterceptor, HttpHandler, HttpEvent, HTTP_INTERCEPTORS, HttpRequest} from '@angular/common/http';
1+
import {Injectable, Optional, Injector, ClassProvider, inject} from '@angular/core';
2+
import {HttpInterceptor, HttpHandler, HttpEvent, HTTP_INTERCEPTORS, HttpRequest, HttpHandlerFn} from '@angular/common/http';
33
import {IGNORED_INTERCEPTORS} from '@anglr/common';
44
import {Observable, Observer, catchError} from 'rxjs';
55

66
import {HttpGatewayTimeoutInterceptorOptions} from './httpGatewayTimeoutInterceptor.options';
77

88
/**
99
* HttpGatewayTimeoutInterceptor used for intercepting http responses and handling 504 statuses
10+
* @deprecated Use new `httpGatewayTimeoutInterceptor` function
1011
*/
1112
@Injectable()
1213
export class HttpGatewayTimeoutInterceptor implements HttpInterceptor
@@ -62,10 +63,53 @@ export class HttpGatewayTimeoutInterceptor implements HttpInterceptor
6263

6364
/**
6465
* Provider for proper use of HttpGatewayTimeoutInterceptor, use this provider to inject this interceptor
66+
* @deprecated Use new `httpGatewayTimeoutInterceptor` function
6567
*/
6668
export const HTTP_GATEWAY_TIMEOUT_INTERCEPTOR_PROVIDER: ClassProvider =
6769
{
6870
provide: HTTP_INTERCEPTORS,
6971
multi: true,
7072
useClass: HttpGatewayTimeoutInterceptor,
7173
};
74+
75+
/**
76+
* Interceptor used for intercepting http responses and handling 504 statuses
77+
*/
78+
export function httpGatewayTimeoutInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>>
79+
{
80+
const injector = inject(Injector);
81+
let options = inject(HttpGatewayTimeoutInterceptorOptions, {optional: true});
82+
83+
if(!(options instanceof HttpGatewayTimeoutInterceptorOptions))
84+
{
85+
options = new HttpGatewayTimeoutInterceptorOptions();
86+
}
87+
88+
return next(req).pipe(catchError(err =>
89+
{
90+
return new Observable(observer =>
91+
{
92+
//client error, not response from server, or is ignored
93+
if(err.error instanceof Error ||
94+
req.context.get(IGNORED_INTERCEPTORS).some(itm => itm == HttpGatewayTimeoutInterceptor))
95+
{
96+
observer.error(err);
97+
observer.complete();
98+
99+
return;
100+
}
101+
102+
//if gateway timeout
103+
if(err.status == 504)
104+
{
105+
options.action(injector, observer as Observer<unknown>);
106+
107+
return;
108+
}
109+
110+
//other errors
111+
observer.error(err);
112+
observer.complete();
113+
}) as Observable<HttpEvent<unknown>>;
114+
}));
115+
}

src/httpInterceptors/httpServerError/httpServerError.interceptor.ts

Lines changed: 72 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import {Injectable, Inject, Optional, ClassProvider} from '@angular/core';
2-
import {HttpInterceptor, HTTP_INTERCEPTORS, HttpEvent, HttpHandler, HttpErrorResponse, HttpRequest} from '@angular/common/http';
1+
import {Injectable, Inject, Optional, ClassProvider, inject} from '@angular/core';
2+
import {HttpInterceptor, HTTP_INTERCEPTORS, HttpEvent, HttpHandler, HttpErrorResponse, HttpRequest, HttpHandlerFn} from '@angular/common/http';
33
import {Logger, LOGGER, IGNORED_INTERCEPTORS} from '@anglr/common';
44
import {Observable, tap} from 'rxjs';
55

66
import {InternalServerErrorService} from '../../services';
77

88
/**
99
* Interceptor that is used for handling http server errors with codes 500..599 and displaying of internal server error
10+
* @deprecated Use new `httpServerErrorInterceptor` function
1011
*/
1112
@Injectable()
1213
export class HttpServerErrorInterceptor implements HttpInterceptor
@@ -29,29 +30,32 @@ export class HttpServerErrorInterceptor implements HttpInterceptor
2930
if(jsDevMode)
3031
{
3132
return next.handle(req)
32-
.pipe(tap(() => {}, err =>
33+
.pipe(tap(
3334
{
34-
//nothing to handle
35-
if (!(err instanceof HttpErrorResponse))
36-
{
37-
return;
38-
}
39-
40-
//client error, not response from server, or is ignored
41-
if (err.error instanceof Error ||
42-
req.context.get(IGNORED_INTERCEPTORS).some(itm => itm == HttpServerErrorInterceptor))
35+
error: err =>
4336
{
44-
return;
45-
}
37+
//nothing to handle
38+
if (!(err instanceof HttpErrorResponse))
39+
{
40+
return;
41+
}
4642

47-
//if server error
48-
if(err.status >= 500 && err.status < 600)
49-
{
50-
this._logger.error('HTTP_ERROR 5xx: url: {{url}} error: {{@ferror}}', {url: err.url, error: err.error});
43+
//client error, not response from server, or is ignored
44+
if (err.error instanceof Error ||
45+
req.context.get(IGNORED_INTERCEPTORS).some(itm => itm == HttpServerErrorInterceptor))
46+
{
47+
return;
48+
}
5149

52-
if(this._internalServerErrorService)
50+
//if server error
51+
if(err.status >= 500 && err.status < 600)
5352
{
54-
this._internalServerErrorService.showInternalServerError(err.error, err.url ?? '');
53+
this._logger.error('HTTP_ERROR 5xx: url: {{url}} error: {{@ferror}}', {url: err.url, error: err.error});
54+
55+
if(this._internalServerErrorService)
56+
{
57+
this._internalServerErrorService.showInternalServerError(err.error, err.url ?? '');
58+
}
5559
}
5660
}
5761
}));
@@ -65,10 +69,58 @@ export class HttpServerErrorInterceptor implements HttpInterceptor
6569

6670
/**
6771
* Provider for proper use of HttpServerErrorInterceptor, use this provider to inject this interceptor
72+
* @deprecated Use new `httpServerErrorInterceptor` function
6873
*/
6974
export const HTTP_SERVER_ERROR_INTERCEPTOR_PROVIDER: ClassProvider =
7075
{
7176
provide: HTTP_INTERCEPTORS,
7277
multi: true,
7378
useClass: HttpServerErrorInterceptor,
7479
};
80+
81+
/**
82+
* Interceptor that is used for handling http server errors with codes 500..599 and displaying of internal server error
83+
*/
84+
export function httpServerErrorInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>>
85+
{
86+
const internalServerErrorService = inject(InternalServerErrorService, {optional: true});
87+
const logger = inject(LOGGER);
88+
89+
if(jsDevMode)
90+
{
91+
return next(req)
92+
.pipe(tap(
93+
{
94+
error: err =>
95+
{
96+
//nothing to handle
97+
if(!(err instanceof HttpErrorResponse))
98+
{
99+
return;
100+
}
101+
102+
//client error, not response from server, or is ignored
103+
if(err.error instanceof Error ||
104+
req.context.get(IGNORED_INTERCEPTORS).some(itm => itm == HttpServerErrorInterceptor))
105+
{
106+
return;
107+
}
108+
109+
//if server error
110+
if(err.status >= 500 && err.status < 600)
111+
{
112+
logger.error('HTTP_ERROR 5xx: url: {{url}} error: {{@error}}', {url: err.url, error: err.error});
113+
114+
if(internalServerErrorService)
115+
{
116+
internalServerErrorService.showInternalServerError(err.error, err.url ?? '');
117+
}
118+
}
119+
}
120+
}));
121+
}
122+
else
123+
{
124+
return next(req);
125+
}
126+
}

src/httpInterceptors/noConnection/noConnection.interceptor.ts

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import {Injectable, Optional, Injector, ClassProvider} from '@angular/core';
2-
import {HttpInterceptor, HttpHandler, HttpEvent, HTTP_INTERCEPTORS, HttpRequest} from '@angular/common/http';
1+
import {Injectable, Optional, Injector, ClassProvider, inject} from '@angular/core';
2+
import {HttpInterceptor, HttpHandler, HttpEvent, HTTP_INTERCEPTORS, HttpRequest, HttpHandlerFn} from '@angular/common/http';
33
import {IGNORED_INTERCEPTORS} from '@anglr/common';
44
import {Observable, Observer, catchError} from 'rxjs';
55

66
import {NoConnectionInterceptorOptions} from './noConnectionInterceptor.options';
77

88
/**
99
* NoConnectionInterceptor used for intercepting http responses and handling 0 statuses
10+
* @deprecated Use new `noConnectionInterceptor` function
1011
*/
1112
@Injectable()
1213
export class NoConnectionInterceptor implements HttpInterceptor
@@ -62,10 +63,53 @@ export class NoConnectionInterceptor implements HttpInterceptor
6263

6364
/**
6465
* Provider for proper use of NoConnectionInterceptor, use this provider to inject this interceptor
66+
* @deprecated Use new `noConnectionInterceptor` function
6567
*/
6668
export const NO_CONNECTION_INTERCEPTOR_PROVIDER: ClassProvider =
6769
{
6870
provide: HTTP_INTERCEPTORS,
6971
multi: true,
70-
useClass: NoConnectionInterceptor
71-
};
72+
useClass: NoConnectionInterceptor,
73+
};
74+
75+
/**
76+
* Interceptor used for intercepting http responses and handling 0 statuses
77+
*/
78+
export function noConnectionInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>>
79+
{
80+
const injector = inject(Injector);
81+
let options = inject(NoConnectionInterceptorOptions, {optional: true});
82+
83+
if(!(options instanceof NoConnectionInterceptorOptions))
84+
{
85+
options = new NoConnectionInterceptorOptions();
86+
}
87+
88+
return next(req).pipe(catchError(err =>
89+
{
90+
return new Observable((observer: Observer<unknown>) =>
91+
{
92+
//client error, not response from server, or is ignored
93+
if(err.error instanceof Error ||
94+
req.context.get(IGNORED_INTERCEPTORS).some(itm => itm == NoConnectionInterceptor))
95+
{
96+
observer.error(err);
97+
observer.complete();
98+
99+
return;
100+
}
101+
102+
//if no connection to server
103+
if(err.status == 0)
104+
{
105+
options.action(injector, observer);
106+
107+
return;
108+
}
109+
110+
//other errors
111+
observer.error(err);
112+
observer.complete();
113+
}) as Observable<HttpEvent<unknown>>;
114+
}));
115+
}

src/httpInterceptors/serviceUnavailable/serviceUnavailable.interceptor.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import {Injectable, Optional, Injector, ClassProvider} from '@angular/core';
2-
import {HttpInterceptor, HttpHandler, HttpEvent, HTTP_INTERCEPTORS, HttpRequest} from '@angular/common/http';
1+
import {Injectable, Optional, Injector, ClassProvider, inject} from '@angular/core';
2+
import {HttpInterceptor, HttpHandler, HttpEvent, HTTP_INTERCEPTORS, HttpRequest, HttpHandlerFn} from '@angular/common/http';
33
import {IGNORED_INTERCEPTORS} from '@anglr/common';
44
import {Observable, Observer, catchError} from 'rxjs';
55

66
import {ServiceUnavailableInterceptorOptions} from './serviceUnavailableInterceptor.options';
77

88
/**
99
* ServiceUnavailableInterceptor used for intercepting http responses and handling 503 statuses
10+
* @deprecated Use new `serviceUnavailableInterceptor` function
1011
*/
1112
@Injectable()
1213
export class ServiceUnavailableInterceptor implements HttpInterceptor
@@ -62,10 +63,53 @@ export class ServiceUnavailableInterceptor implements HttpInterceptor
6263

6364
/**
6465
* Provider for proper use of ServiceUnavailableInterceptor, use this provider to inject this interceptor
66+
* @deprecated Use new `serviceUnavailableInterceptor` function
6567
*/
6668
export const SERVICE_UNAVAILABLE_INTERCEPTOR_PROVIDER: ClassProvider =
6769
{
6870
provide: HTTP_INTERCEPTORS,
6971
multi: true,
7072
useClass: ServiceUnavailableInterceptor,
7173
};
74+
75+
/**
76+
* Interceptor used for intercepting http responses and handling 503 statuses
77+
*/
78+
export function serviceUnavailableInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>>
79+
{
80+
const injector = inject(Injector);
81+
let options = inject(ServiceUnavailableInterceptorOptions, {optional: true});
82+
83+
if(!(options instanceof ServiceUnavailableInterceptorOptions))
84+
{
85+
options = new ServiceUnavailableInterceptorOptions();
86+
}
87+
88+
return next(req).pipe(catchError(err =>
89+
{
90+
return new Observable(observer =>
91+
{
92+
//client error, not response from server, or is ignored
93+
if(err.error instanceof Error ||
94+
req.context.get(IGNORED_INTERCEPTORS).some(itm => itm == ServiceUnavailableInterceptor))
95+
{
96+
observer.error(err);
97+
observer.complete();
98+
99+
return;
100+
}
101+
102+
//if service unavailable
103+
if(err.status == 503)
104+
{
105+
options.action(injector, observer as Observer<unknown>);
106+
107+
return;
108+
}
109+
110+
//other errors
111+
observer.error(err);
112+
observer.complete();
113+
}) as Observable<HttpEvent<unknown>>;
114+
}));
115+
}

0 commit comments

Comments
 (0)