Я создал глобальный обработчик ошибок в своем приложении Angular 6:
основной метод обработчика ошибок:
handleError(error: Error | HttpErrorResponse) {
const router = this.injector.get(Router);
const notificationService = this.injector.get(NotificationsService);
this._logger(error);
if (!navigator.onLine) {
notificationService.displayNotification('error', 'timespan', {heading: 'Internet connection lost!', body: ''});
} else if (error instanceof HttpErrorResponse) {
notificationService.displayNotification('error', 'click', this._httpErrorMessage(error));
} else {
// CLIENT error
router.navigate(['/error-page']);
}
}
Проблема: Многие из вызовов службы HTTP выполняются в резолверах:
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<ClientDetailsModel> {
if (route.params.cif) {
const reqBody = new GetClientDetailsRequestModel({cif: route.params.cif, idWewPrac: this.userContext.getUserSKP()});
return this.clientsService.getClientDetails(reqBody)
.pipe(
map((clientDetails: { customerDetails: ClientDetailsModel }) => {
if (clientDetails.customerDetails) {
return clientDetails.customerDetails;
}
return null;
})
);
}
Если в таком вызове возникает ошибка Http, ошибка, полученная моим глобальным обработчиком ошибок, формируется как HttpErrorResponse, заключенный внутри Error (сообщение об ошибке - HttpErrorResponse):
Uncaught (in promise): HttpErrorResponse: {"headers":{"normalizedNames":{},"lazyUpdate":null},"status":400,"statusText":"OK","url":"https://...
Если Http-ошибки возникают вне решателей, глобальный обработчик ошибок работает нормально.
Чтобы достичь своей цели (выброс HttpErrorResponse из резольвера), мне нужно указать способ обработки ошибки в обратном вызове ошибки внутри подписки, но я не могу этого сделать, потому что резолвер - это тот, кто управляет подпиской.
Есть ли способ указать, как преобразователь должен обрабатывать ошибки?
Я бы хотел избежать ручного анализа этих обернутых ошибок.
Я искал решение, но смог создать только рабочий цикл.
Это проверит текст HttpErrorResponse и попытается проанализировать JSON, что приведет к реальному объекту ошибки.
Совсем не здорово, но лучше, чем ничего.
handleError(error: any): void {
console.error('Errorhandler catched error: ' + error.message, error);
// We need to have this little hack in oder to access the real error object
// The Angular resolver / promise wraps the error into the message, serialized as json.
// So we extract this error again.
// But first lets check if we actually dealing with an HttpErrorResponse ...
if (error.message.search('HttpErrorResponse: ')) {
// The error includes an HTTPErrorResponse, so we try to parse it's values ...
const regex = new RegExp('^.*HttpErrorResponse:\\s(\\{.*\\})$');
const matches = regex.exec(error.message);
if (matches !== null) {
// matches the regex, convert...
const httpErrorResponse = JSON.parse(matches[1]); // This is now the real error object with all the fields
this.handleHttpErrorResponse(httpErrorResponse);
} else {
// It contains HttpErrorResponse, but no JSON part...
this.toastr.error('There was an unknown communication error',
'Communication error',
{timeOut: 10000});
}
} else {
this.toastr.error('Unknown error occured',
'Well that should not happen. Check the log for more information...',
{timeOut: 10000});
}
}
Та же проблема с Angular 7. Вы нашли решение?