При работе с сетью и http нередко могут происходить ошибки, например, в момент запроса сеть стала недоступна, неправильно указан адрес и соответственно не найден ресурс, либо доступ к ресурсу ограничен, либо другие ошибки. Перехват ошибок позволит выяснить проблему и каким-то образом обработать их, например, вывести пользователю сообщение об ошибке.
Для перехвата ошибок, которые могут возникнуть при выполнении запроса, можно использовать функцию catchError(). Так, возьмем код сервиса из прошлой темы и добавим к нему обработку ошибок:
import {Injectable} from "@angular/core"; import {HttpClient} from "@angular/common/http"; import {User} from "./user"; import {Observable} from "rxjs"; import { map, catchError} from "rxjs/operators"; @Injectable() export class HttpService{ errorMessage: String = ""; constructor(private http: HttpClient){ } getUsers() : Observable<User[]> { return this.http.get("assets/users.json").pipe(map((data:any)=>{ let usersList = data["userList"]; return usersList.map(function(user:any) : User { return new User(user.userName, user.userAge); }); }), catchError(err => { console.log(err); this.errorMessage = err.message; return []; })) }; }
Прежде всего в сервисе определяется переменная errorMessage
, которая будет хранит информацию об ошибке.
Для имитации ошибки в http-клиент передается заведомо несуществующий адрес "users.json". Для обработки ошибок в метод
pipe()
передается в качестве второго параметра функция для обработки ошибок. В качестве подобной функции здесь применяется функция catchError():
catchError(err => { console.log(err); this.errorMessage = err.message; return []; })
В качестве параметра функция catchError()
принимает функцию, в которую в качестве параметра передается объект ошибки, возникшей
при выполнении запроса. Таким образом, в этой функции мы можем получить ошибку и обработать ее.
Ошибка собственно представляет объект, из которого мы можем получить ряд данных. В частности, свойство message позволяет получить сообщение об ошибке, а свойство status - статусный код ответа.
Так, в данном случае вся обработка заключается в том, что этот объект выводится на консоль, а свойству errorMessage сервиса передается сообщение об ошибке (если запрос прошел успешно, то этому свойству присваивается пустая строка).
Стоит отметить, что в функции обработки ошибки нам все равно надо вернуть объект Observable. Для этого мы возвращаем пустой массив:
return [];
Далее будет создан объект Observable<User[]>, который будет содержать пустой массив объектов User.
Например, используем сервис и для этого изменим код компонента AppComponent:
import { Component, OnInit} from "@angular/core"; import { HttpClientModule} from "@angular/common/http"; import { HttpService} from "./http.service"; import {User} from "./user"; @Component({ selector: "my-app", standalone: true, imports: [HttpClientModule], template: `<div>{{this.httpService.errorMessage}}</div> <ul> @for(user of users; track $index){ <li>{{user?.name}} ({{user?.age}})</li> } </ul>`, providers: [HttpService] }) export class AppComponent implements OnInit { users: User[]=[]; constructor(public httpService: HttpService){} ngOnInit(){ this.httpService.getUsers().subscribe({next:(data: User[]) => this.users=data}); } }
С помощью метода subscribe()
компонент может получить из сервиса массив объектов User. Если возникнет ошибка, то это будет пустой массив.
Для получения информации об ошибке компонент обращается к свойству errorMessage
сервиса и выводит его значение в размеке html.
И например, при обащении к несуществующему файлу json мы получим следующую ошибку:
Это самая примитивная обработка ошибка, которая демонстрирует общий принцип. Естественно в сервисе мы можем определять какое-то другое сообщение об ошибке или как-то иначе обрабатывать ошибку.