Bạn có một số tùy chọn, tùy thuộc vào nhu cầu của bạn. Nếu bạn muốn xử lý lỗi trên cơ sở từng yêu cầu, hãy thêm một catch
vào yêu cầu của bạn. Nếu bạn muốn thêm một giải pháp toàn cầu, hãy sử dụng HttpInterceptor
.
Mở plunker demo hoạt động ở đây cho các giải pháp bên dưới.
tl; dr
Trong trường hợp đơn giản nhất, bạn chỉ cần thêm một .catch()
hoặc một .subscribe()
, như:
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)
);
Nhưng có nhiều chi tiết hơn về điều này, xem bên dưới.
Giải pháp phương pháp (cục bộ): lỗi nhật ký và trả về phản hồi dự phòng
Nếu bạn chỉ cần xử lý lỗi ở một nơi, bạn có thể sử dụng catch
và trả về giá trị mặc định (hoặc phản hồi trống) thay vì thất bại hoàn toàn. Bạn cũng không cần .map
chỉ để ép kiểu, bạn có thể sử dụng một hàm chung. Nguồn: Angular.io - Lấy chi tiết lỗi .
Vì vậy, một .get()
phương pháp chung , sẽ giống như:
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>();
});
}
}
Xử lý lỗi sẽ cho phép ứng dụng của bạn tiếp tục ngay cả khi dịch vụ tại URL ở trong tình trạng không tốt.
Giải pháp theo yêu cầu này chủ yếu tốt khi bạn muốn trả về một phản hồi mặc định cụ thể cho từng phương thức. Nhưng nếu bạn chỉ quan tâm đến việc hiển thị lỗi (hoặc có phản hồi mặc định chung), giải pháp tốt hơn là sử dụng bộ chặn, như được mô tả bên dưới.
Chạy plunker demo đang hoạt động tại đây .
Sử dụng nâng cao: Chặn tất cả các yêu cầu hoặc phản hồi
Một lần nữa, hướng dẫn Angular.io cho thấy:
Một tính năng chính của @angular/common/http
là đánh chặn, khả năng khai báo các trình đánh chặn nằm giữa ứng dụng của bạn và chương trình phụ trợ. Khi ứng dụng của bạn đưa ra một yêu cầu, các bộ chặn sẽ biến đổi nó trước khi gửi đến máy chủ và các bộ chặn có thể chuyển đổi phản hồi theo cách của nó trở lại trước khi ứng dụng của bạn nhìn thấy nó. Điều này hữu ích cho mọi thứ từ xác thực đến ghi nhật ký.
Tất nhiên, có thể được sử dụng để xử lý lỗi một cách rất đơn giản ( demo plunker tại đây ):
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>>();
});
}
}
Cung cấp công cụ chặn của bạn: Chỉ cần khai báo những điều HttpErrorInterceptor
trên không khiến ứng dụng của bạn sử dụng nó. Bạn cần kết nối nó trong mô-đun ứng dụng của mình bằng cách cung cấp nó như một thiết bị đánh chặn, như sau:
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 {}
Lưu ý: Nếu bạn có cả bộ chặn lỗi và một số xử lý lỗi cục bộ, thì có khả năng sẽ không có xử lý lỗi cục bộ nào được kích hoạt, vì lỗi sẽ luôn được bộ đánh chặn xử lý trước khi nó đến bộ xử lý lỗi cục bộ.
Chạy plunker demo đang hoạt động tại đây .
return this.httpClient.get<type>(...)
. và sau đó cócatch...
một nơi nào đó ngoài dịch vụ nơi anh ta thực sự sử dụng nó bởi vì đó là nơi anh ta sẽ xây dựng luồng có thể quan sát và có thể xử lý nó tốt nhất.