您有一些选择,具体取决于您的需要。如果您想在每个请求的基础上处理错误,请catch
在您的请求中添加一个。如果要添加全局解决方案,请使用HttpInterceptor
.
在此处打开以下解决方案的工作演示 plunker。
tl;博士
在最简单的情况下,您只需要添加 a.catch()
或 a .subscribe()
,例如:
import 'rxjs/add/operator/catch'; // don't forget this, or you'll get a runtime error
this.httpClient
.get("data-url")
.catch((err: HttpErrorResponse) => {
// simple logging, but you can do a lot more, see below
console.error('An error occurred:', err.error);
});
// or
this.httpClient
.get("data-url")
.subscribe(
data => console.log('success', data),
error => console.log('oops', error)
);
但还有更多细节,见下文。
方法(本地)解决方案:记录错误并返回回退响应
如果您只需要在一个地方处理错误,您可以使用catch
并返回一个默认值(或空响应),而不是完全失败。您也不需要.map
只是强制转换,您可以使用通用函数。来源:Angular.io - 获取错误详细信息。
所以,一个通用的.get()
方法,就像:
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from "@angular/common/http";
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/empty';
import 'rxjs/add/operator/retry'; // don't forget the imports
@Injectable()
export class DataService {
baseUrl = 'http://localhost';
constructor(private httpClient: HttpClient) { }
// notice the <T>, making the method generic
get<T>(url, params): Observable<T> {
return this.httpClient
.get<T>(this.baseUrl + url, {params})
.retry(3) // optionally add the retry
.catch((err: HttpErrorResponse) => {
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
console.error('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.error(`Backend returned code ${err.status}, body was: ${err.error}`);
}
// ...optionally return a default fallback value so app can continue (pick one)
// which could be a default value
// return Observable.of<any>({my: "default value..."});
// or simply an empty observable
return Observable.empty<T>();
});
}
}
即使 URL 处的服务状况不佳,处理错误也将允许您的应用程序继续运行。
当您想要为每个方法返回特定的默认响应时,这种按请求解决方案非常有用。但是,如果您只关心错误显示(或具有全局默认响应),则更好的解决方案是使用拦截器,如下所述。
在此处运行工作演示 plunker。
高级用法:拦截所有请求或响应
Angular.io 指南再次显示:
一个主要特性@angular/common/http
是拦截,能够声明位于应用程序和后端之间的拦截器。当您的应用程序发出请求时,拦截器在将其发送到服务器之前对其进行转换,并且拦截器可以在您的应用程序看到它之前在返回的路上转换响应。这对于从身份验证到日志记录的所有事情都很有用。
当然,它可以用来以非常简单的方式处理错误(这里是 demo plunker):
import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse,
HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/empty';
import 'rxjs/add/operator/retry'; // don't forget the imports
@Injectable()
export class HttpErrorInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request)
.catch((err: HttpErrorResponse) => {
if (err.error instanceof Error) {
// A client-side or network error occurred. Handle it accordingly.
console.error('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.error(`Backend returned code ${err.status}, body was: ${err.error}`);
}
// ...optionally return a default fallback value so app can continue (pick one)
// which could be a default value (which has to be a HttpResponse here)
// return Observable.of(new HttpResponse({body: [{name: "Default value..."}]}));
// or simply an empty observable
return Observable.empty<HttpEvent<any>>();
});
}
}
提供您的拦截器:简单地声明HttpErrorInterceptor
上述内容不会导致您的应用程序使用它。您需要通过提供它作为拦截器将其连接到您的应用程序模块中,如下所示:
import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpErrorInterceptor } from './path/http-error.interceptor';
@NgModule({
...
providers: [{
provide: HTTP_INTERCEPTORS,
useClass: HttpErrorInterceptor,
multi: true,
}],
...
})
export class AppModule {}
注意:如果你有一个错误拦截器和一些本地错误处理,很可能不会触发任何本地错误处理,因为错误总是在它到达本地错误处理之前由拦截器处理。
在此处运行工作演示 plunker。