У вас есть несколько вариантов, в зависимости от ваших потребностей. Если вы хотите обрабатывать ошибки для каждого запроса, добавьте catch
в свой запрос. Если вы хотите добавить глобальное решение, используйтеHttpInterceptor
.
Откройте здесь рабочий демонстрационный плункер для решений ниже.
tl; dr
В простейшем случае вам просто нужно добавить a .catch()
или a .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 - Получение сведений об ошибке .
Итак, общий .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-адресу находится в плохом состоянии.
Это решение для каждого запроса хорошо в основном, когда вы хотите вернуть конкретный ответ по умолчанию для каждого метода. Но если вас интересует только отображение ошибок (или есть глобальный ответ по умолчанию), лучшим решением будет использование перехватчика, как описано ниже.
Запустите рабочий демонстрационный плункер здесь .
Расширенное использование: перехват всех запросов или ответов
Еще раз, руководство Angular.io показывает:
Основная особенность @angular/common/http
- это перехват, возможность объявлять перехватчики, которые находятся между вашим приложением и серверной частью. Когда ваше приложение делает запрос, перехватчики преобразуют его перед отправкой на сервер, а перехватчики могут преобразовать ответ на обратном пути до того, как ваше приложение его увидит. Это полезно для всего, от аутентификации до регистрации.
Что, конечно же, можно использовать для обработки ошибок очень простым способом ( демонстрационный плункер здесь ):
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
вышеуказанного не заставляет ваше приложение его использовать. Вам необходимо подключить его к модулю вашего приложения , предоставив его в качестве перехватчика, как показано ниже:
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 {}
Примечание: если у вас есть и перехватчик ошибок, и некоторая локальная обработка ошибок, естественно, вероятно, что локальная обработка ошибок никогда не будет запущена, поскольку ошибка всегда будет обрабатываться перехватчиком до того, она достигнет локальной обработки ошибок.
Запустите рабочий демонстрационный плункер здесь .
return this.httpClient.get<type>(...)
. а затем иметьcatch...
место вне службы, где он фактически потребляет ее, потому что именно там он будет строить поток наблюдаемых объектов и может справиться с этим лучше всего.Promise<Object>
клиента (вызывающегоDataService
методы) для обработки ошибки. Пример:this.dataService.post('url', {...}).then(...).catch((e) => console.log('handle error here instead', e));
. Выберите то, что понятнее вам и пользователям вашего сервиса.return Observable.of({my: "default value..."});
выдает ошибку «| ...» не может быть присвоено типу «HttpEvent <any>».HttpEvent
, например , какHttpResponse
. Так, например, вы можете использовать:return Observable.of(new HttpResponse({body: [{name: "Default value..."}]}));
. Я обновил ответ, чтобы прояснить этот момент. Кроме того, я создал рабочий демонстрационный плункер, чтобы показать, что все работает: plnkr.co/edit/ulFGp4VMzrbaDJeGqc6q?p=previewПозвольте мне пожалуйста уточните acdcjunior ответ «сек об использовании HttpInterceptor с новейшими функциями RxJs (v.6).
источник
С появлением
HTTPClient
API был не толькоHttp
заменен API, но и добавлен новый -HttpInterceptor
API.AFAIK одна из его целей - добавить поведение по умолчанию ко всем исходящим запросам и входящим ответам HTTP.
Итак, предполагая, что вы хотите добавить поведение обработки ошибок по умолчанию , добавив
.catch()
ко всем вашим возможным методам http.get / post / etc до смешного сложно поддерживать.Это можно сделать следующим образом, например, используя
HttpInterceptor
:// app.module.ts
Дополнительная информация для OP: вызов http.get / post / etc без строгого типа не является оптимальным использованием API. Ваш сервис должен выглядеть так:
Возврат
Promises
из ваших методов обслуживания вместоObservables
- еще одно плохое решение.И дополнительный совет: если вы используете TYPE сценарий , начните использовать его часть типа. Вы теряете одно из самых больших преимуществ языка: знание типа значения, с которым вы имеете дело.
Если вам нужен, на мой взгляд, хороший пример Angular-сервиса, обратите внимание на следующую суть .
источник
this.http.get()
и т. Д., А неthis.get()
т. Д.DataService
?Довольно просто (по сравнению с тем, как это было сделано в предыдущем API).
Источник из официального руководства по Angular (скопируйте и вставьте)
источник
Для Angular 6+ .catch не работает напрямую с Observable. Вы должны использовать
Ниже код:
Дополнительные сведения см. В Руководстве по Angular для Http.
источник
Пример службы обработки ошибок Angular 8 HttpClient
api.service.ts
источник
Вероятно, вы захотите иметь что-то вроде этого:
Это также сильно зависит от того, как вы используете свой сервис, но это основной случай.
источник
После ответа @acdcjunior вот как я его реализовал
служба:
звонящий:
источник
источник
Если вы не можете обнаружить ошибки ни с одним из предложенных здесь решений, возможно, сервер не обрабатывает запросы CORS.
В этом случае Javascript, а тем более Angular, может получить доступ к информации об ошибке.
Ищите предупреждения в консоли, которые включают
CORB
илиCross-Origin Read Blocking
.Кроме того, изменился синтаксис для обработки ошибок (как описано в каждом другом ответе). Теперь вы используете конвейерные операторы, например:
источник
Используя Interceptor, вы можете поймать ошибку. Ниже приведен код:
Вы можете предпочесть этот блог .. приведенный простой пример.
источник