Anda memiliki beberapa pilihan, tergantung pada kebutuhan Anda. Jika Anda ingin menangani kesalahan berdasarkan permintaan, tambahkan a catch
ke permintaan Anda. Jika Anda ingin menambahkan solusi global, gunakan HttpInterceptor
.
Buka di sini plunker demo yang berfungsi untuk solusi di bawah ini.
tl; dr
Dalam kasus yang paling sederhana, Anda hanya perlu menambahkan a .catch()
atau .subscribe()
, seperti:
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)
);
Tetapi ada lebih banyak detail untuk ini, lihat di bawah.
Solusi metode (lokal): kesalahan log dan respons fallback kembali
Jika Anda perlu menangani kesalahan hanya di satu tempat, Anda dapat menggunakan catch
dan mengembalikan nilai default (atau respons kosong) alih-alih gagal sepenuhnya. Anda juga tidak perlu .map
hanya untuk mentransmisikan, Anda dapat menggunakan fungsi generik. Sumber: Angular.io - Mendapatkan Detail Kesalahan .
Jadi, .get()
metode umum , akan seperti:
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>();
});
}
}
Menangani kesalahan akan memungkinkan aplikasi Anda untuk melanjutkan bahkan ketika layanan di URL dalam kondisi buruk.
Solusi per permintaan ini baik terutama saat Anda ingin mengembalikan respons default tertentu ke setiap metode. Tetapi jika Anda hanya peduli dengan tampilan kesalahan (atau memiliki respons default global), solusi yang lebih baik adalah menggunakan pencegat, seperti yang dijelaskan di bawah ini.
Jalankan plunker demo yang berfungsi di sini .
Penggunaan lanjutan: Mencegah semua permintaan atau tanggapan
Sekali lagi, panduan Angular.io menunjukkan:
Fitur utama dari @angular/common/http
adalah intersepsi, kemampuan untuk mendeklarasikan interseptor yang berada di antara aplikasi Anda dan backend. Saat aplikasi Anda membuat permintaan, interseptor mengubahnya sebelum mengirimnya ke server, dan interseptor bisa mengubah respons dalam perjalanan kembali sebelum aplikasi Anda melihatnya. Ini berguna untuk segala hal mulai dari otentikasi hingga logging.
Yang, tentu saja, dapat digunakan untuk menangani kesalahan dengan cara yang sangat sederhana ( demo plunker di sini ):
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>>();
});
}
}
Menyediakan interseptor Anda: Cukup mendeklarasikan hal di HttpErrorInterceptor
atas tidak akan menyebabkan aplikasi Anda menggunakannya. Anda perlu menyambungkannya dalam modul aplikasi Anda dengan menyediakannya sebagai pencegat, sebagai berikut:
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 {}
Catatan: Jika Anda memiliki kedua pencegat kesalahan dan beberapa penanganan kesalahan lokal, secara alami, ada kemungkinan bahwa ada kesalahan penanganan lokal akan pernah dipicu, karena kesalahan akan selalu ditangani oleh pencegat sebelum mencapai penanganan kesalahan lokal.
Jalankan plunker demo yang berfungsi di sini .
return this.httpClient.get<type>(...)
. dan kemudian memilikicatch...
suatu tempat di luar layanan di mana dia benar-benar mengonsumsinya karena di situlah dia akan membangun aliran yang dapat diamati dan dapat menanganinya dengan baik.