【问题标题】:Angular 5 log interceptor throwed error but calling function cannot read back the errorAngular 5 日志拦截器抛出错误,但调用函数无法读回错误
【发布时间】:2017-12-01 20:25:24
【问题描述】:

拦截器代码:

import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
// import { tap, map, catchError } from 'rxjs/operators';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/do';

@Injectable()
export class LogInterceptor implements HttpInterceptor {

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        console.log(`HTTP: ${req.urlWithParams}`);

        return next.handle(req)
            .catch((err, caught) => {
                console.log(err);
                if (err.error instanceof Error) {
                    // A client-side or network error occurred. Handle it accordingly.
                    console.log('An error occurred:', err.error.message);
                } else {
                    // The backend returned an unsuccessful response code.
                    // The response body may contain clues as to what went wrong,
                    console.log(`Backend returned code ${err.status}, body was: ${err.error.message}`);
                }
                return Observable.throw(err);
            })
            .do(event => {
                console.log(event);
                if (event instanceof HttpResponse) {
                    console.log(event.body);
                }
            });
    }

}

拦截器正在工作,但调用函数无法读取错误,并且始终为空。

调用函数

this.http.post<Asset>(`whatever.php`, {}).subscribe(
  _data => console.log(data), 
  _err => console.log(_err) // <- this _err is always NULL 
);

如果在拦截器中删除了 catch 代码,则错误又回来了。我希望拦截器进行通用处理,但也允许调用函数在需要时处理错误。有可能吗?

【问题讨论】:

    标签: angular angular-http-interceptors angular-httpclient


    【解决方案1】:
    return next.handle(req).do(
          (event: HttpEvent < any > ) => {
            if (event instanceof HttpResponse) {
              console.log('--> event: ', event);
              console.log('--> status: ', event.status);
              this._spinnerService.requestEnded();
            }
          },
          (err: any) => { <-- The error is caught here. You didn't define any Error callback, hence it's null during your subscription.
            if (err instanceof HttpErrorResponse) {
              console.log('--> error: ', err);
              console.log('--> errorStatus: ', err.status);
              this._spinnerService.requestEnded();
            }
          }
        );
    

    查看我的回答中的评论

    【讨论】:

    • 我确实在原始代码中返回了 observable.throw。您能分享正确的代码应该如何吗?谢谢!
    • do 操作符几乎类似于 subscribe 操作符,它返回 3 个回调:成功、错误和完成回调。实现拦截器的正确方法是:.do(success => {}, error? => {}, completed => {})。如果您希望调用函数从拦截器中捕获错误,则必须在 do 运算符中传递错误回调。您永远无法在调用函数中记录错误,因为在请求实际到达服务器之前捕获并抛出错误,这意味着数据也是空/未定义的。如果获取到数据,则表示没有错误,do 运算符执行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多