Angular GlobalErrorHandler и HttpErrorResponse - преобразователь, выбрасывающий неправильно отформатированный HttpErrorResponse
Я создал глобальный обработчик ошибок в своем приложении 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 из resolver), мне нужно указать способ обработки ошибок при обратном вызове ошибок внутри подписки, но я не могу этого сделать, потому что решатель - это тот, кто управляет подпиской.
Есть ли способ указать, как распознаватель должен обрабатывать ошибки?
Я хотел бы избежать ручного разбора этих завернутых ошибок.
0 ответов
Я искал решение, но смог создать только рабочий цикл.
Это проверит текст 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});
}
}