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.Promise<Object>
klien (pemanggilDataService
metode) untuk menangani kesalahan. Contoh:this.dataService.post('url', {...}).then(...).catch((e) => console.log('handle error here instead', e));
. Pilih apa saja yang lebih jelas bagi Anda dan pengguna layanan Anda.return Observable.of({my: "default value..."});
Ini memberikan kesalahan "| ... 'tidak dapat ditetapkan untuk mengetik' HttpEvent <any> '."HttpEvent
, seperti aHttpResponse
. Jadi, misalnya, Anda bisa menggunakan:return Observable.of(new HttpResponse({body: [{name: "Default value..."}]}));
. Saya telah memperbarui jawaban untuk memperjelas hal ini. Juga, saya membuat plunker demo yang berfungsi untuk menunjukkan semuanya berfungsi: plnkr.co/edit/ulFGp4VMzrbaDJeGqc6q?p=previewMari saya perbarui acdcjunior jawaban 's tentang menggunakan HttpInterceptor dengan fitur RxJs terbaru (ayat 6).
sumber
Dengan hadirnya
HTTPClient
API, API tidak hanyaHttp
diganti, tetapi yang baru telah ditambahkan,HttpInterceptor
API.AFAIK salah satu tujuannya adalah menambahkan perilaku default ke semua permintaan keluar HTTP dan tanggapan masuk.
Jadi mengasumsikan bahwa Anda ingin menambahkan perilaku penanganan kesalahan default , menambahkan
.catch()
ke semua kemungkinan metode http.get / post / etc Anda sangat sulit untuk dipertahankan.Ini dapat dilakukan dengan cara berikut sebagai contoh menggunakan a
HttpInterceptor
:// app.module.ts
Beberapa info tambahan untuk OP: Memanggil http.get / post / etc tanpa tipe yang kuat bukanlah penggunaan API yang optimal. Layanan Anda akan terlihat seperti ini:
Kembali
Promises
dari metode layanan Anda, bukanObservables
keputusan buruk lainnya.Dan saran tambahan: jika Anda menggunakan skrip TYPE , mulailah menggunakan bagian type. Anda kehilangan salah satu keuntungan terbesar dari bahasa tersebut: mengetahui jenis nilai yang Anda hadapi.
Jika Anda menginginkan, menurut pendapat saya, contoh yang baik dari layanan sudut, lihat inti berikut .
sumber
this.http.get()
dll dan tidakthis.get()
dll diDataService
?Cukup mudah (dibandingkan dengan cara melakukannya dengan API sebelumnya).
Sumber dari (salin dan tempel) panduan resmi Angular
sumber
Untuk Angular 6+, .catch tidak bekerja secara langsung dengan Observable. Anda harus menggunakan
Kode di bawah ini:
Untuk lebih jelasnya, rujuk ke Angular Guide for Http
sumber
Angular 8 Contoh Layanan Penanganan Error HttpClient
api.service.ts
sumber
Anda mungkin ingin memiliki sesuatu seperti ini:
Ini juga sangat tergantung bagaimana Anda menggunakan layanan Anda, tetapi ini adalah kasus dasar.
sumber
Mengikuti jawaban @acdcjunior, beginilah cara saya menerapkannya
layanan:
penelepon:
sumber
sumber
Jika Anda tidak dapat menemukan kesalahan dengan solusi apa pun yang disediakan di sini, mungkin server tidak menangani permintaan CORS.
Dalam acara tersebut, Javascript, apalagi Angular, dapat mengakses informasi kesalahan.
Cari peringatan di konsol Anda yang menyertakan
CORB
atauCross-Origin Read Blocking
.Selain itu, sintaksis telah berubah untuk menangani kesalahan (seperti yang dijelaskan di setiap jawaban lainnya). Anda sekarang menggunakan operator yang dapat menggunakan pipa, seperti:
sumber
Dengan menggunakan Interceptor Anda dapat menangkap kesalahan. Di bawah ini adalah kode:
Anda dapat memilih blog ini .. diberikan contoh sederhana untuk itu.
sumber