根据你的需要,你有一些 Select .如果您想按每个请求处理错误,请在请求中添加catch
.如果要添加全局解决方案,请使用HttpInterceptor
.
打开here the working demo plunker获取以下解决方案.
tl;dr
在最简单的情况下,只需添加.catch()
或.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)
);
但关于这一点还有更多细节,请参见下面的内容.
Method (local) solution: log error and return fallback response
如果只需要在一个地方处理错误,可以使用catch
并返回默认值(或空响应),而不是完全失败.你也不需要.map
来强制转换,你可以使用一个通用函数.资料来源:Angular.io - Getting Error Details.
所以,一个通用的.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上的服务状况不佳.
当您想要向每个方法返回特定的默认响应时,这种按请求的解决方案最好.但是,如果您只关心错误显示(或具有全局默认响应),则更好的解决方案是使用拦截器,如下所述.
跑working demo plunker here.
Advanced usage: Intercepting all requests or responses
再一次,Angular.io guide个节目:
@angular/common/http
的一个主要特性是拦截,即声明位于应用程序和后端之间的拦截器的能力.当您的应用程序发出请求时,拦截器会在将其发送到服务器之前对其进行转换,并且拦截器可以在您的应用程序看到响应之前在返回的途中对其进行转换.这对于从身份验证到日志(log)记录的一切都很有用.
当然,可以用一种非常简单的方法来处理错误(demo plunker here):
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>>();
});
}
}
Providing your interceptor:简单地声明上面的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 {}
Note:如果你有both个错误拦截器和一些本地错误处理,很自然地,很可能不会触发任何本地错误处理,因为错误总是由拦截器before处理,然后到达本地错误处理.
跑working demo plunker here.