diff --git a/src/lib/error/index.ts b/src/lib/error/index.ts index bf107e8..d4c7ff3 100644 --- a/src/lib/error/index.ts +++ b/src/lib/error/index.ts @@ -1,5 +1,5 @@ export * from './error.service'; -export * from './max-retries.token'; +export * from './tokens'; export * from './server-error-interceptor'; export * from './full-page-error/full-page-error.component'; export * from './connection-status/connection-status.component'; diff --git a/src/lib/error/server-error-interceptor.ts b/src/lib/error/server-error-interceptor.ts index 4ac4dbb..4a4e7be 100644 --- a/src/lib/error/server-error-interceptor.ts +++ b/src/lib/error/server-error-interceptor.ts @@ -2,7 +2,7 @@ import { HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest import { Inject, Injectable, Optional } from '@angular/core'; import { MonoTypeOperatorFunction, Observable, retry, throwError, timer } from 'rxjs'; import { catchError, tap } from 'rxjs/operators'; -import { MAX_RETRIES_ON_SERVER_ERROR } from './max-retries.token'; +import { MAX_RETRIES_ON_SERVER_ERROR, SERVER_ERROR_SKIP_PATHS } from './tokens'; import { ErrorService } from './error.service'; import { KeycloakService } from 'keycloak-angular'; @@ -14,12 +14,22 @@ function updateSeconds(seconds: number) { } } -function backoffOnServerError(maxRetries = 3): MonoTypeOperatorFunction> { +function isNotServerError(error: HttpErrorResponse) { + return error.status < HttpStatusCode.InternalServerError && error.status !== 0; +} + +function isPathSkipped(path: string, skippedPaths: string[]) { + const sanitized = path.replace('https://', '').replace('http://', ''); + const pathWithoutHost = sanitized.split(/\/(.*)/s)[1]; + return skippedPaths.some(skippedPath => pathWithoutHost === skippedPath); +} + +function backoffOnServerError(maxRetries = 3, skippedPaths: string[] = []): MonoTypeOperatorFunction> { let seconds = 0; function delay(error: HttpErrorResponse) { seconds = updateSeconds(seconds); - if (error.status < HttpStatusCode.InternalServerError && error.status !== 0) { + if (isNotServerError(error) || (error.url && isPathSkipped(error.url, skippedPaths))) { return throwError(() => error); } @@ -39,6 +49,7 @@ export class ServerErrorInterceptor implements HttpInterceptor { private readonly _errorService: ErrorService, private readonly _keycloakService: KeycloakService, @Optional() @Inject(MAX_RETRIES_ON_SERVER_ERROR) private readonly _maxRetries: number, + @Optional() @Inject(SERVER_ERROR_SKIP_PATHS) private readonly _skippedPaths: string[], ) {} intercept(req: HttpRequest, next: HttpHandler): Observable> { @@ -50,14 +61,14 @@ export class ServerErrorInterceptor implements HttpInterceptor { } // server error - if (error.status >= HttpStatusCode.InternalServerError) { + if (error.status >= HttpStatusCode.InternalServerError && error.url && !isPathSkipped(error.url, this._skippedPaths)) { this._errorService.set(error); this._urlsWithError.add(req.url); } return throwError(() => error); }), - backoffOnServerError(this._maxRetries || 3), + backoffOnServerError(this._maxRetries, this._skippedPaths), tap(() => { if (this._urlsWithError.has(req.url)) { this._errorService.setOnline(); diff --git a/src/lib/error/max-retries.token.ts b/src/lib/error/tokens.ts similarity index 56% rename from src/lib/error/max-retries.token.ts rename to src/lib/error/tokens.ts index b2ad58a..af359ca 100644 --- a/src/lib/error/max-retries.token.ts +++ b/src/lib/error/tokens.ts @@ -1,3 +1,4 @@ import { InjectionToken } from '@angular/core'; export const MAX_RETRIES_ON_SERVER_ERROR = new InjectionToken('Number of retries before giving up'); +export const SERVER_ERROR_SKIP_PATHS = new InjectionToken('A list of paths to skip when handling server errors');