错误:类型“ void”不能分配给类型“ HttpEvent <any>”

时间:2020-10-23 10:07:47

标签: angular ionic-framework angular-http-interceptors

我想拦截http响应,尤其是在出现401之类的错误时。所以我在toPromise之后使用catch块。但是我在下面出现错误。

错误:输入'void | HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse | HttpUserEvent”不能分配给“ HttpEvent”类型。 不能将类型“ void”分配给类型“ HttpEvent”。

这是我的拦截器代码。您能说出代码中的错误并给出解决方案吗?谢谢

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 个答案:

答案 0 :(得分:1)

我在里面加了一些评论:

--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<---