Tratando erros em Angular
Ao trabalhar com redes e requisições HTTP, é comum ocorrerem erros, como quando a rede fica indisponível durante uma requisição, um endereço incorreto é fornecido e, consequentemente, o recurso não é encontrado, ou o acesso ao recurso é restrito, entre outros problemas. A interceptação de erros permite identificar o problema e tratá-lo de alguma forma, como exibindo uma mensagem de erro ao usuário.
Para capturar os erros que podem ocorrer ao fazer uma requisição, podemos usar a função catchError()
. Vamos usar o código de serviço da seção anterior e adicionar o tratamento de erros:
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 [];
})
);
}
}
Primeiramente, no serviço, definimos a variável errorMessage
, que armazenará as informações sobre o erro.
Para simular um erro, passamos um endereço incorreto "users.json"
para o cliente HTTP. O tratamento de erros é feito através do método pipe()
, onde a função catchError()
é usada como o segundo parâmetro para capturar erros:
catchError((err) => {
console.log(err);
this.errorMessage = err.message;
return [];
});
A função catchError()
recebe como parâmetro uma função que, por sua vez, aceita um objeto de erro lançado durante a execução da requisição. Dessa forma, podemos obter o erro e tratá-lo.
O erro em si é um objeto do qual podemos extrair várias informações. Por exemplo, a propriedade message
nos dá a mensagem de erro, enquanto a propriedade status
indica o código de status da resposta.
No exemplo acima, o tratamento do erro consiste em exibir o objeto no console e atribuir a mensagem de erro à propriedade errorMessage
do serviço (se a requisição for bem-sucedida, esse campo receberá uma string vazia).
Vale destacar que, na função de tratamento de erros, ainda é necessário retornar um objeto Observable
. Para isso, retornamos um array vazio:
return [];
Assim, será criado um objeto Observable<User[]>
que conterá um array vazio de objetos User.
Vamos utilizar o serviço e modificar o código do componente AppComponent
:
import { Component, OnInit } from "@angular/core";
import { HttpService } from "./http.service";
import { User } from "./user";
@Component({
selector: "my-app",
standalone: true,
imports: [],
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),
});
}
}
Usando o método subscribe()
, o componente pode obter um array de objetos User
do serviço. Se ocorrer um erro, o array será vazio.
Para exibir informações sobre o erro, o componente acessa a propriedade errorMessage do serviço e exibe seu valor no template HTML.
Por exemplo, ao tentar acessar um arquivo JSON inexistente, a seguinte mensagem de erro será exibida:
Este é um exemplo básico de tratamento de erros, que demonstra o princípio geral. Obviamente, podemos definir outras mensagens de erro ou lidar com os erros de outras maneiras dentro do serviço.