您有一些選擇,根據您的需要。如果您想要按照每個請求處理錯誤,請將catch
添加到您的請求中。如果您想添加全局解決方案,請使用HttpInterceptor
。
打開here the working demo plunker獲取以下解決方案。
TL;博士
在最簡單的情況下,你只需要添加一個.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)
);
但也有更多的細節,這一點,見下文。
方法(本地)解決方案:登錄錯誤並返回備用響應
如果需要只在一個地方處理錯誤,你可以使用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>();
});
}
}
處理錯誤可以讓你的應用程序繼續,即使在網址的服務是在惡劣的條件下。
這種按請求的解決方案主要是在您想要爲每種方法返回特定的默認響應時。但是,如果您只關心顯示錯誤(或者有全局默認響應),則更好的解決方案是使用攔截器,如下所述。
運行working demo plunker here。
高級應用:攔截所有請求或響應
再次,Angular.io guide顯示:
A major feature of @angular/common/http
is interception, the ability to declare interceptors which sit in between your application and the backend. When your application makes a request, interceptors transform it before sending it to the server, and the interceptors can transform the response on its way back before your application sees it. This is useful for everything from authentication to logging.
其中,當然,可以用非常簡單的方式來處理錯誤(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>>();
});
}
}
提供您的攔截器:只需聲明上述HttpErrorInterceptor
不會導致您的應用使用它。你需要wire it up in your app module通過提供它作爲一個攔截器,如下:
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 {}
注:如果你有既錯誤攔截和一些地方的錯誤處理,自然,很可能沒有本地錯誤處理將永遠被觸發,因爲錯誤將總是由攔截器在之前處理,它達到本地錯誤處理。
運行working demo plunker here。
好了,如果他想成爲完全看中,他將離開他的服務完全清楚:'返回this.httpClient.get(...)' 。然後在他實際使用的服務的某個地方「捕捉......」,因爲那些地方他將構建可觀察流量並且能夠最好地處理它。 –
return Observable.of(e);爲我工作 這種方式我可以推遲到來電者的異常處理 – LastTribunal
我同意,也許一個最佳的解決方案將是'Promise