1
votes

I want to intercept http response, especially if any errors like 401. So I am using catch block after toPromise. But I am getting error below.

Error : Type 'void | HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse | HttpUserEvent' is not assignable to type 'HttpEvent'. Type 'void' is not assignable to type 'HttpEvent'.

Here is my interceptor code. Can you tell what is wrong in code and give solution. Thanks

import { Injectable } from '@angular/core';
import {
    HttpInterceptor,
    HttpEvent,
    HttpResponse,
    HttpErrorResponse,
    HttpRequest,
    HttpHandler,
    HttpHeaders
} from '@angular/common/http';
import { TokenService } from '../services/token.service';
import { environment } from 'src/environments/environment';
import { observable, Observable, throwError } from 'rxjs';
import { fromPromise } from 'rxjs/internal-compatibility';

@Injectable()
export class CustomHttpInterceptor implements HttpInterceptor {
    constructor(private tokenService: TokenService,
        private authService: AuthService) {
    }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return fromPromise(this.handleAccess(request, next));
    }

    private async handleAccess(request: HttpRequest<any>, next: HttpHandler): Promise<HttpEvent<any>> {
        const token = await this.tokenService.getToken();
        const lang = localStorage.getItem('pref_lang');
        
        let changedRequest = request;
       
        const headerSettings: { [name: string]: string | string[]; } = {};

        for (const key of request.headers.keys()) {
            headerSettings[key] = request.headers.getAll(key);
        }
        if (token) {
            headerSettings['Authorization'] = 'Bearer ' + token;
        }
        
        headerSettings['Content-Type'] = 'application/json';
        headerSettings['Accept-Language'] = lang;

        const newHeader = new HttpHeaders(headerSettings);
        changedRequest = request.clone({
            headers: newHeader
        });
        return next.handle(changedRequest).toPromise().catch(error => {
            console.log('HttpErrorResponse error', error);
            if (error instanceof HttpErrorResponse) {
                console.log('HttpErrorResponse error status code', error.status);
                switch ((<HttpErrorResponse>error).status) {
                    case 401:
                        return this.handle401Error(request, next);
                }
            } else {
                console.log('something went wrong error', error);
            }
        });
    }

    handle401Error(req: HttpRequest<any>, next: HttpHandler) {
    console.log('handle401Error called...');
    if (!this.isRefreshingToken) {
        this.isRefreshingToken = true;
        let cachedRequest = req;
        this.authService.getFreshAccessToken().then((res) => {
            next.handle(cachedRequest).toPromise();
        }).catch(error => {
             this.authService.logout();
        }).finally(() => {
            cachedRequest = null;
            this.isRefreshingToken = false;
        });
    }
}

}
1

1 Answers

1
votes

I put some comments inside:

--8<---
            if (error instanceof HttpErrorResponse) {
                console.log('HttpErrorResponse error status code', error.status);
                switch ((<HttpErrorResponse>error).status) {
                    case 401:
                        return this.handle401Error(request, next);
                    // here, you're missing the default-case. HttpErrorResponses other than status 401 are completely ignored and the return-type will be void, as the else-statement below is never reached
                }
            } else {
                // you should return something here, as not returning anything at all is the same as returning void
                console.log('something went wrong error', error);
            }
            // the default could be to just rethrow the error to let the caller handle it. This should also remove the compiler error
            throw error;
--8<---