猿问

如何从http.request()正确捕获异常?

我的部分代码:


import {Injectable} from 'angular2/core';

import {Http, Headers, Request, Response} from 'angular2/http';

import {Observable} from 'rxjs/Observable';

import 'rxjs/add/operator/map';


@Injectable()

export class myClass {


  constructor(protected http: Http) {}


  public myMethod() {

    let request = new Request({

      method: "GET",

      url: "http://my_url"

    });


    return this.http.request(request)

      .map(res => res.json())

      .catch(this.handleError); // Trouble line. 

                                // Without this line code works perfectly.

  }


  public handleError(error: Response) {

    console.error(error);

    return Observable.throw(error.json().error || 'Server error');

  }


}

myMethod() 在浏览器的控制台中产生异常:


原来的例外:TypeError:this.http.request(...)。map(...)。catch不是函数


慕婉清6462132
浏览 1734回答 3
3回答

慕标琳琳

也许您可以尝试在导入中添加以下内容:import 'rxjs/add/operator/catch';您也可以这样做:return this.http.request(request)  .map(res => res.json())  .subscribe(    data => console.log(data),    err => console.log(err),    () => console.log('yay')  );每个评论:例外:TypeError:Observable_1.Observable.throw不是函数同样,为此,您可以使用:import 'rxjs/add/observable/throw';

繁星coding

更新了新服务以使用HttpClientModule和RxJS v5.5.x:import { Injectable }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; from '@angular/core';import { HttpClient, HttpErrorResponse } from '@angular/common/http';import { Observable }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; from 'rxjs/Observable';import { catchError, tap }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;from 'rxjs/operators';import { SomeClassOrInterface}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;from './interfaces';import 'rxjs/add/observable/throw';@Injectable()&nbsp;export class MyService {&nbsp; &nbsp; url = 'http://my_url';&nbsp; &nbsp; constructor(private _http:HttpClient) {}&nbsp; &nbsp; private handleError(operation: String) {&nbsp; &nbsp; &nbsp; &nbsp; return (err: any) => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let errMsg = `error in ${operation}() retrieving ${this.url}`;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(`${errMsg}:`, err)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(err instanceof HttpErrorResponse) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // you could extract more info about the error if you want, e.g.:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(`status: ${err.status}, ${err.statusText}`);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // errMsg = ...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Observable.throw(errMsg);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; // public API&nbsp; &nbsp; public getData() : Observable<SomeClassOrInterface> {&nbsp; &nbsp; &nbsp; &nbsp; // HttpClient.get() returns the body of the response as an untyped JSON object.&nbsp; &nbsp; &nbsp; &nbsp; // We specify the type as SomeClassOrInterfaceto get a typed result.&nbsp; &nbsp; &nbsp; &nbsp; return this._http.get<SomeClassOrInterface>(this.url)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .pipe(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tap(data => console.log('server data:', data)),&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catchError(this.handleError('getData'))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; }旧服务,它使用了已弃用的HttpModule:import {Injectable}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; from 'angular2/core';import {Http, Response, Request} from 'angular2/http';import {Observable}&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; from 'rxjs/Observable';import 'rxjs/add/observable/throw';//import 'rxjs/Rx';&nbsp; // use this line if you want to be lazy, otherwise:import 'rxjs/add/operator/map';import 'rxjs/add/operator/do';&nbsp; // debugimport 'rxjs/add/operator/catch';@Injectable()export class MyService {&nbsp; &nbsp; constructor(private _http:Http) {}&nbsp; &nbsp; private _serverError(err: any) {&nbsp; &nbsp; &nbsp; &nbsp; console.log('sever error:', err);&nbsp; // debug&nbsp; &nbsp; &nbsp; &nbsp; if(err instanceof Response) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return Observable.throw(err.json().error || 'backend server error');&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // if you're using lite-server, use the following line&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // instead of the line above:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //return Observable.throw(err.text() || 'backend server error');&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return Observable.throw(err || 'backend server error');&nbsp; &nbsp; }&nbsp; &nbsp; private _request = new Request({&nbsp; &nbsp; &nbsp; &nbsp; method: "GET",&nbsp; &nbsp; &nbsp; &nbsp; // change url to "./data/data.junk" to generate an error&nbsp; &nbsp; &nbsp; &nbsp; url: "./data/data.json"&nbsp; &nbsp; });&nbsp; &nbsp; // public API&nbsp; &nbsp; public getData() {&nbsp; &nbsp; &nbsp; &nbsp; return this._http.request(this._request)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // modify file data.json to contain invalid JSON to have .json() raise an error&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .map(res => res.json())&nbsp; // could raise an error if invalid JSON&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .do(data => console.log('server data:', data))&nbsp; // debug&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .catch(this._serverError);&nbsp; &nbsp; }}我现在使用.do()(进行调试)。 .tap()当发生服务器错误时,我从正在使用的服务器(精简服务器)获取body的Response对象的内容仅包含文本,因此我err.text()在上面使用的原因而不是在err.json().error。您可能需要为服务器调整该行。如果res.json()由于无法解析JSON数据而引发错误,_serverError则不会获取Response对象,因此进行instanceof检查的原因。在此plunker,更改url为,./data/data.junk以生成错误。两种服务的用户都应具有可以处理该错误的代码:@Component({&nbsp; &nbsp; selector: 'my-app',&nbsp; &nbsp; template: '<div>{{data}}</div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;<div>{{errorMsg}}</div>`})export class AppComponent {&nbsp; &nbsp; errorMsg: string;&nbsp; &nbsp; constructor(private _myService: MyService ) {}&nbsp; &nbsp; ngOnInit() {&nbsp; &nbsp; &nbsp; &nbsp; this._myService.getData()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .subscribe(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data => this.data = data,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; err&nbsp; => this.errorMsg = <any>err&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; }}
随时随地看视频慕课网APP
我要回答