7 } from '@angular/common/http';
8 import { Injectable } from '@angular/core';
9 import { Router } from '@angular/router';
11 import * as _ from 'lodash';
12 import { Observable, throwError as observableThrowError } from 'rxjs';
13 import { catchError } from 'rxjs/operators';
15 import { NotificationType } from '../enum/notification-type.enum';
16 import { CdNotificationConfig } from '../models/cd-notification';
17 import { FinishedTask } from '../models/finished-task';
18 import { AuthStorageService } from './auth-storage.service';
19 import { NotificationService } from './notification.service';
20 import { ServicesModule } from './services.module';
23 providedIn: ServicesModule
25 export class ApiInterceptorService implements HttpInterceptor {
27 private router: Router,
28 private authStorageService: AuthStorageService,
29 public notificationService: NotificationService
32 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
33 return next.handle(request).pipe(
34 catchError((resp) => {
35 if (resp instanceof HttpErrorResponse) {
36 let timeoutId: number;
37 switch (resp.status) {
39 const finishedTask = new FinishedTask();
41 const task = resp.error.task;
42 if (_.isPlainObject(task)) {
43 task.metadata.component = task.metadata.component || resp.error.component;
45 finishedTask.name = task.name;
46 finishedTask.metadata = task.metadata;
48 finishedTask.metadata = resp.error;
51 finishedTask.success = false;
52 finishedTask.exception = resp.error;
53 timeoutId = this.notificationService.notifyTask(finishedTask);
56 this.authStorageService.remove();
57 this.router.navigate(['/login']);
60 this.router.navigate(['/403']);
63 timeoutId = this.prepareNotification(resp);
67 * Decorated preventDefault method (in case error previously had
68 * preventDefault method defined). If called, it will prevent a
69 * notification to be shown.
71 resp['preventDefault'] = () => {
72 this.notificationService.cancel(timeoutId);
76 * If called, it will prevent a notification for the specific status code.
77 * @param {number} status The status code to be ignored.
79 resp['ignoreStatusCode'] = function(status: number) {
80 if (this.status === status) {
81 this.preventDefault();
85 // Return the error to the method that called it.
86 return observableThrowError(resp);
91 private prepareNotification(resp): number {
92 return this.notificationService.show(() => {
94 if (_.isPlainObject(resp.error) && _.isString(resp.error.detail)) {
95 message = resp.error.detail; // Error was triggered by the backend.
96 } else if (_.isString(resp.error)) {
98 } else if (_.isString(resp.message)) {
99 message = resp.message;
101 return new CdNotificationConfig(
102 NotificationType.error,
103 `${resp.status} - ${resp.statusText}`,