http.get中的.catch()没有捕获HTTP 500错误代码

时间:2016-11-20 00:58:09

标签: angular observable

在我的Angular 2应用程序中,我有一个带有http.get方法的服务,该方法返回一个Observable。

campaign.service.ts

public getCampaign(campaignId: string): Observable<Campaign> {
  return this.http.get(this.campaignsUrl + '/' + campaignId, options)
    .map(this.extractData)
    .catch(this.handleError);
}

private extractData(res: Response) {
  let body = res.json();
  return body.data || body || {};
}

private handleError(error: Response | any) {
  // In a real world app, we might use a remote logging infrastructure
  let errMsg: string;
  if (error instanceof Response) {
    const body = error.json() || '';
    const err = body.error || JSON.stringify(body);
    errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
  } else {
    errMsg = error.message ? error.message : error.toString();
  }
  console.error(errMsg);
  return Observable.throw(errMsg);
}

然后我在我的Component中调用它,就像这样:

campaign.component.ts

this.campaignService.getCampaign(paramId)
  .subscribe(
    obj => {
      // do something
    },
    () => {
      // handle error here
    }
  });

但是,如果http.get调用返回HTTP 500,我从未点击我的Service类中的.catch(...)部分。控制台输出未捕获的异常。

GET http://localhost:9001/api/v1/campaigns/4175edc4 500 (Internal Server Error)
EXCEPTION: Response with status: 500 Internal Server Error for URL: http://localhost:9001/api/v1/campaigns/4175edc4
Uncaught Response {_body: "{"message":"invalid input syntax for uuid: \"4175edc4\""}", status: 500, ok: false, statusText: "Internal Server Error", headers: Headers…}

我在这里做错了什么?

3 个答案:

答案 0 :(得分:2)

Angular 2遵循Fetch规范,only throws errors when there was a problem with the request operation。如果返回错误响应,它不会抛出(因为错误响应仍然是有效的响应)。

您需要检查response.ok属性以确保它不是404或500等。

答案 1 :(得分:0)

感谢您的评论@Jon。我很难做到这一点。这是我的代码(直接来自Angular2文档):

  testGet(): Observable<any> {
    return this.http.get(this.someUrl + '/toError405')
                    .map(this.extractData)
                    .catch(this.handleError);
  }

  private extractData(res: Response) {
    let body = res.json();
    return body.data || { };
  }

  private handleError (error: Response | any) {
    // In a real world app, we might use a remote logging infrastructure
    let errMsg: string;
    if (error instanceof Response) {
      const body = error.json() || '';
      const err = body.error || JSON.stringify(body);
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`;
    } else {
      errMsg = error.message ? error.message : error.toString();
    }
    console.error(errMsg);
    return Observable.throw(errMsg);
  }  

正如您所看到的,我强制执行405错误,我在控制台的“网络”选项卡中看到了这个错误。但是,extractData()handleError()都不会被击中。处理这个问题的最佳方法是什么?谢谢。

答案 2 :(得分:0)

如果声明的函数不在对象的上下文中声明,则将为其分配全局上下文。因此,当我们希望闭包(内部函数)引用我们的父对象之一时,我们要么必须保留对象的值,要么将对象绑定到函数。

尝试一下:

.catch(this.handleError.bind(this));