Este artigo demonstra algumas abordagens de tratamento de erros ao trabalhar com a API Fetch. A API Fetch permite fazer uma solicitação a um recurso de rede remoto. Quando você faz uma chamada de rede remota, sua página da Web fica sujeita a vários possíveis erros de rede.
As seções a seguir descrevem possíveis erros e como escrever um código que forneça um nível razoável de funcionalidade resistente a erros e condições de rede inesperadas. Um código resiliente mantém os usuários satisfeitos e mantém um nível padrão de serviço para seu site.
Prever possíveis erros de rede
Esta seção descreve um cenário em que o usuário cria um novo vídeo chamado
"My Travels.mp4"
e, em seguida, tenta fazer upload do vídeo em um site de compartilhamento de vídeo.
Ao trabalhar com a busca, é fácil considerar o caminho da felicidade em que o usuário envia o vídeo. No entanto, há outros caminhos que não são tão simples, mas que os desenvolvedores da Web precisam planejar. Esses caminhos (infelizes) podem acontecer devido a erros do usuário, condições ambientais inesperadas ou a um bug no site de compartilhamento de vídeos.
Exemplos de erros do usuário
- O usuário carrega um arquivo de imagem (como JPEG) em vez de um arquivo de vídeo.
- O usuário começa a enviar o arquivo de vídeo errado. Em seguida, no meio do upload, o usuário especifica o arquivo de vídeo correto para enviar.
- O usuário acidentalmente clica em "Cancelar upload" enquanto o vídeo está sendo enviado.
Exemplos de mudanças ambientais
- A conexão de Internet fica off-line durante o upload do vídeo.
- O navegador será reiniciado durante o upload do vídeo.
- Os servidores do site de compartilhamento de vídeo são reiniciados durante o upload do vídeo.
Exemplos de erros com o site de compartilhamento de vídeos
- O site de compartilhamento de vídeo não pode processar um nome de arquivo com um espaço. Em vez de
"My Travels.mp4"
, ele espera um nome como"My_Travels.mp4"
ou"MyTravels.mp4"
. - O site de compartilhamento de vídeo não pode fazer upload de um vídeo que exceda o tamanho máximo de arquivo aceitável.
- O site de compartilhamento de vídeo não é compatível com o codec do vídeo enviado.
Esses exemplos podem e acontecem no mundo real. Talvez você já tenha visto esses exemplos no passado. Vamos escolher um exemplo de cada uma das categorias anteriores e discutir os seguintes pontos:
- Qual será o comportamento padrão se o serviço de compartilhamento de vídeo não puder lidar com o exemplo dado?
- O que o usuário espera que aconteça no exemplo?
- Como podemos melhorar o processo?
Solucionar erros com a API Fetch
Os exemplos de código a seguir usam await
de nível superior (suporte a navegadores) porque esse recurso pode simplificar o código.
Quando a API Fetch gera erros
Esse exemplo usa uma instrução de bloco try
/catch
para capturar erros gerados no bloco try
. Por exemplo, se a API Fetch não conseguir buscar o recurso especificado, um erro será gerado. Em um bloco catch
como esse, forneça uma experiência do usuário significativa. Se um ícone de carregamento, uma interface do usuário comum que representa algum tipo de progresso, for mostrado ao usuário, você poderá realizar as seguintes ações em um bloco catch
:
- Remova o ícone de carregamento da página.
- Forneça mensagens úteis que expliquem o que deu errado e quais opções o usuário pode escolher.
- Com base nas opções disponíveis, apresente um botão "Tentar novamente" ao usuário.
- Em segundo plano, envie os detalhes do erro para seu serviço de rastreamento de erros ou para o back-end. Essa ação registra o erro para que ele possa ser diagnosticado posteriormente.
try {
const response = await fetch('https://website');
} catch (error) {
// TypeError: Failed to fetch
console.log('There was an error', error);
}
Posteriormente, enquanto diagnostica o erro registrado, crie um caso de teste para capturar esse erro antes que os usuários saibam que há algo errado. Dependendo do erro, o teste pode ser de unidade, integração ou aceitação.
Quando o código de status da rede representa um erro
Este exemplo de código faz uma solicitação a um serviço de teste HTTP que sempre responde com o código de status HTTP 429 Too Many Requests
. É interessante observar que a resposta não chega ao bloco catch
. Um status 404, entre alguns códigos de status, não retorna um erro de rede, mas é resolvido normalmente.
Para verificar se o código de status HTTP foi bem-sucedido, você pode usar uma das seguintes opções:
- Use a propriedade
Response.ok
para determinar se o código de status estava no intervalo de200
a299
. - Use a propriedade
Response.status
para determinar se a resposta foi bem-sucedida. - Use outros metadados, como
Response.headers
, para avaliar se a resposta foi bem-sucedida.
let response;
try {
response = await fetch('https://httpbin.org/status/429');
} catch (error) {
console.log('There was an error', error);
}
// Uses the 'optional chaining' operator
if (response?.ok) {
console.log('Use the response here!');
} else {
console.log(`HTTP Response Code: ${response?.status}`)
}
A prática recomendada é trabalhar com as pessoas da sua organização e da equipe para entender possíveis códigos de status de resposta HTTP. Às vezes, os desenvolvedores de back-end, as operações de desenvolvimento e os engenheiros de serviço podem fornecer insights exclusivos sobre possíveis casos extremos que talvez você não tenha previsto.
Quando ocorre um erro ao analisar a resposta da rede
Este exemplo de código demonstra outro tipo de erro que pode surgir com a análise de um corpo de resposta. A interface Response
oferece métodos convenientes para analisar diferentes tipos de dados, como texto ou JSON. No código a seguir, uma solicitação de rede é feita para um serviço de teste HTTP que retorna uma string HTML como o corpo da resposta. No entanto, há uma tentativa de analisar o corpo da resposta como JSON, o que gera um erro.
let json;
try {
const response = await fetch('https://httpbin.org/html');
json = await response.json();
} catch (error) {
if (error instanceof SyntaxError) {
// Unexpected token < in JSON
console.log('There was a SyntaxError', error);
} else {
console.log('There was an error', error);
}
}
if (json) {
console.log('Use the JSON here!', json);
}
Você deve preparar seu código para aceitar uma variedade de formatos de resposta e verificar se uma resposta inesperada não quebra a página da Web para o usuário.
Considere o seguinte cenário: você tem um recurso remoto que retorna uma resposta JSON válida e ele é analisado com o método Response.json()
. Pode acontecer de o serviço ficar inativo. Depois de inativo, uma 500 Internal Server Error
é retornada. Se as técnicas adequadas de tratamento de erros não forem usadas durante a análise de JSON, a página poderá ser interrompida para o usuário, porque um erro não processado será gerado.
Quando a solicitação de rede precisa ser cancelada antes de ser concluída
Neste exemplo de código, um AbortController
é usado para cancelar uma solicitação em andamento. Uma solicitação em andamento é uma solicitação de rede que foi iniciada, mas não foi concluída.
Os cenários em que pode ser necessário cancelar uma solicitação em andamento podem variar, mas isso depende do caso de uso e do ambiente. O código a seguir demonstra como transmitir um AbortSignal
para a API Fetch. O AbortSignal
é anexado a um AbortController
, e o AbortController
inclui um método abort()
, o que significa para o navegador que a solicitação de rede precisa ser cancelada.
const controller = new AbortController();
const signal = controller.signal;
// Cancel the fetch request in 500ms
setTimeout(() => controller.abort(), 500);
try {
const url = 'https://httpbin.org/delay/1';
const response = await fetch(url, { signal });
console.log(response);
} catch (error) {
// DOMException: The user aborted a request.
console.log('Error: ', error)
}
Conclusão
Um aspecto importante do tratamento de erros é definir as várias partes que podem dar errado. Para cada cenário, verifique se você tem um substituto adequado para o usuário. Em relação a uma solicitação de busca, faça a si mesmo perguntas como:
- O que acontece se o servidor de destino ficar inativo?
- O que acontece se a busca receber uma resposta inesperada?
- O que acontece se a conexão de Internet do usuário falhar?
Dependendo da complexidade da página, você também pode esboçar um fluxograma que descreve a funcionalidade e a interface do usuário para diferentes cenários.