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

我的部分代码:

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()在浏览器的控制台中产生exception:

ORIGINAL EXCEPTION:TypeError:this.http.request(…)。map(…)。catch不是一个函数

也许你可以尝试在你的导入中添加这个:

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

新服务更新为使用HttpClientModule:

 import { Injectable } from '@angular/core'; import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import { catchError } from 'rxjs/operators'; import { SomeTypeOrInterface } from './interfaces'; import 'rxjs/add/observable/throw'; @Injectable() export class MyService { url = 'http://my_url'; constructor(private _http:HttpClient) {} private handleError(operation: String) { return (err: any) => { let errMsg = `error in ${operation}() retrieving ${this.url}`; console.log(`${errMsg}:`, err) if(err instanceof HttpErrorResponse) { // you could extract more info about the error if you want, eg: console.log(`status: ${err.status}, ${err.statusText}`); // errMsg = ... } return Observable.throw(errMsg); } } // public API public getData() : Observable<SomeTypeOrInterface> { // HttpClient.get() returns the body of the response as an untyped JSON object. // We specify the type as SomeTypeOrInterface to get a typed result. return this._http.get<SomeTypeOrInterface>(this.assetUrl) .pipe( catchError(this.handleError('getData')) ); } 

旧服务,它使用不推荐的HttpModule:

 import {Injectable} from 'angular2/core'; import {Http, Response, Request} from 'angular2/http'; import {Observable} from 'rxjs/Observable'; import 'rxjs/add/observable/throw'; //import 'rxjs/Rx'; // use this line if you want to be lazy, otherwise: import 'rxjs/add/operator/map'; import 'rxjs/add/operator/do'; // debug import 'rxjs/add/operator/catch'; @Injectable() export class MyService { constructor(private _http:Http) {} private _serverError(err: any) { console.log('sever error:', err); // debug if(err instanceof Response) { return Observable.throw(err.json().error || 'backend server error'); // if you're using lite-server, use the following line // instead of the line above: //return Observable.throw(err.text() || 'backend server error'); } return Observable.throw(err || 'backend server error'); } private _request = new Request({ method: "GET", // change url to "./data/data.junk" to generate an error url: "./data/data.json" }); // public API public getData() { return this._http.request(this._request) // modify file data.json to contain invalid JSON to have .json() raise an error .map(res => res.json()) // could raise an error if invalid JSON .do(data => console.log('server data:', data)) // debug .catch(this._serverError); } } 

我使用.do()进行debugging。

当出现服务器错误时,从我使用的服务器(lite-server)获取的Response对象body仅包含文本,因此我使用上面的err.text()而不是err.json().error 。 您可能需要为您的服务器调整该行。

如果res.json()由于无法parsingJSON数据而引发错误, _serverError将不会得到一个Response对象,因此是检查instanceof的原因。

在这个plunker中 ,将url更改为./data/data.junk以生成错误。


任一服务的用户都应该有可以处理错误的代码:

 @Component({ selector: 'my-app', template: '<div>{{data}}</div> <div>{{errorMsg}}</div>` }) export class AppComponent { errorMsg: string; constructor(private _myService: MyService ) {} ngOnInit() { this._myService.getData() .subscribe( data => this.data = data, err => this.errorMsg = <any>err ); } } 

在最新版本的angular4中使用

 import { Observable } from 'rxjs/Rx' 

它会导入所有需要的东西。

RxJSfunction需要专门导入。 一个简单的方法是将import * as Rx from "rxjs/Rx"所有functionimport * as Rx from "rxjs/Rx"

然后确保以Rx.Observable访问Observable类。