【问题标题】:Can't catch a http error in component无法捕获组件中的 http 错误
【发布时间】:2018-11-30 14:44:35
【问题描述】:

我遇到了 Angular 5、HTTP 拦截器和 errorHandler 的问题。

我发送一个 http 请求。响应可以是 200 或 404(如果数据不存在)。 200 与订阅组件完美配合。 404 是不同的,因为我使用 HttpInterceptor 从角度。如果有错误,“catch error”函数会发回一个 Observable 错误,但我无法从我的服务或组件中捕获这个错误,我不知道为什么。

test.component.ts

this.testService.findByProducId(product.id).subscribe(data => {

                console.log(data); 

                // processing
            },
            err => {
                console.log(err); // nothing here :(

            });

test.service.ts

    findByProductId(productId){
        let url = this.getUrl() + "/product/" + productId;

        // headers
        let headers = this.setHttpHeaders();

    return this.http.get(url, {headers: headers})
        .map(res => res).share();
    }

httpListener(拦截器)

@Injectable()
export class HttpListener implements HttpInterceptor {

    countRequest: number = 0;
    countResponse: number = 0;
    logEnable: boolean = environment.logEnable;
    logUrl: string = environment.logUrl;

    constructor(
        @Inject( LoaderService ) public loaderService: LoaderService,
        @Inject( Router ) public router: Router) {
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        this.loaderService.show();
        this.countRequest++;

        return next.handle(req).pipe(
            map(event => {
                if (event instanceof HttpResponse) {
                    if (this.logEnable) {
                        // log data
                    }
                } 

                return event;
            }),
            catchError(error => {
                if (this.logEnable) {
                    // log data
                }

                switch(error.status) {
                    case 400: {
                        break;
                    }

                    // not authorized
                    case 401: {
                        this.router.navigate(["/"]);
                        break;
                    }
                    case 404: {
                        // my specific 404 case
                        if (!this.router.url.includes("/test/create")) {

                        }
                        else {

                            // I want to return the error to my service.
                        }
                    }
                }

                return Observable.throw(error);
            }),
            finalize(() => {

                this.countResponse++;

                if (this.countRequest == this.countResponse) {
                    this.loaderService.hide();

                    this.countRequest = 0;
                    this.countResponse = 0;
                }
            })
        )
    }
}

非常感谢!

【问题讨论】:

  • 抛出404后程序是否进入catchError
  • 是的,就是这样。我可以在 catchError 函数中看到一个错误,但我无法将其发回(我尝试使用 Observable,但我的服务或组件中没有出现任何内容)
  • 你为什么在 HttpInterceptor 中捕捉到这个错误?调用服务时应该使用 catchError,并在那里检查 404。
  • 拦截器“拦截”所有http请求,当出现错误时会向客户端显示通知(顺便发送日志)。

标签: angular rxjs


【解决方案1】:

试试这个,它对我有用

组件.ts

this.testService.findByProducId(product.id).subscribe(

    data => console.log('success', data),
    error => console.log('oops', error));

service.ts

return this.http.get(url, {headers: headers}) 
            .map((response: Response) =>response.json())               

【讨论】:

  • 我尝试了您的代码,但订阅中没有任何内容。即使进入服务,我也有一个 console.log 但什么也没有。我不明白:(哦,我编译时出现了一些错误。我会尽快编辑我的评论
  • 我可以编译,但问题仍然存在。没有回到我的组件。我的服务中也有同样的事情(我试图 console.log 响应)
【解决方案2】:

我终于找到了问题所在。我的拦截器中的函数“catchError”似乎停止了这个过程。这是好的代码(也许我可以使用“catch”功能但我有一个错误):

            error => {
                if (this.logEnable) {
                    // log data
                }

                switch(error.status) {
                    case 400: {
                        break;
                    }

                    // not authorized
                    case 401: {
                        this.router.navigate(["/"]);
                        break;
                    }
                    case 404: {
                        // my specific 404 case
                        if (!this.router.url.includes("/test/create")) {

                        }
                        else {

                            // I want to return the error to my service.
                            Observable.of(error);
                        }
                    }
                }

                return Observable.throw(error);
            }),

【讨论】:

    猜你喜欢
    • 2022-01-11
    • 2020-05-22
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    相关资源
    最近更新 更多