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 os possíveis erros e como escrever códigos que proporcionem um nível razoável de funcionalidade resistente a erros e condições inesperadas da rede. O código resiliente mantém os usuários satisfeitos e um nível padrão de serviço para seu site.
Antecipe 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 tenta fazer o upload dele em um site de compartilhamento de vídeos.
Ao trabalhar com o Fetch, é fácil considerar o caminho ideal em que o usuário faz o upload do vídeo. No entanto, há outros caminhos que não são tão simples, mas que os desenvolvedores Web precisam planejar. Esses caminhos (infelizes) podem acontecer devido a um erro do usuário, condições ambientais inesperadas ou um bug no site de compartilhamento de vídeos.
Exemplos de erros do usuário
- O usuário faz o upload de 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. Então, no meio do envio, o usuário especifica o arquivo de vídeo correto para envio.
- O usuário clica acidentalmente em "Cancelar envio" enquanto o vídeo está sendo enviado.
Exemplos de mudanças ambientais
- A conexão de Internet fica off-line enquanto o vídeo é enviado.
- O navegador é reiniciado durante o upload do vídeo.
- Os servidores do site de compartilhamento de vídeos são reiniciados enquanto o vídeo está sendo enviado.
Exemplos de erros no site de compartilhamento de vídeos
- O site de compartilhamento de vídeos não consegue processar um nome de arquivo com 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 enviar um vídeo que exceda o tamanho máximo aceitável.
- O site de compartilhamento de vídeos não é compatível com o codec do vídeo enviado.
Esses exemplos podem e acontecem no mundo real. Talvez você já tenha encontrado exemplos como esse no passado. Vamos escolher um exemplo de cada uma das categorias anteriores e discutir os seguintes pontos:
- Qual é o comportamento padrão se o serviço de compartilhamento de vídeo não conseguir processar o exemplo fornecido?
- O que o usuário espera que aconteça no exemplo?
- Como podemos melhorar o processo?
Processar erros com a API Fetch
Os exemplos de código a seguir usam await
de nível superior (suporte a navegador) porque esse recurso pode simplificar seu código.
Quando a API Fetch gera erros
Este exemplo usa uma instrução 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, ofereça uma experiência significativa ao usuário. Se uma interface comum que representa algum tipo de progresso, como um ícone de carregamento, for mostrada ao usuário, você poderá realizar as seguintes ações em um bloco catch
:
- Remova o ícone de carregamento da página.
- Mostre mensagens úteis que expliquem o que deu errado e as opções que o usuário pode seguir.
- 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 mais tarde.
try {
const response = await fetch('https://website');
} catch (error) {
// TypeError: Failed to fetch
console.log('There was an error', error);
}
Em uma fase posterior, enquanto você diagnostica o erro registrado, é possível escrever um caso de teste para detectar esse erro antes que os usuários percebam que algo está 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
Esse 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
. Curiosamente, a resposta não chega ao bloco catch
. O status 404, entre alguns outros 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, use 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 na sua organização e equipe para entender possíveis códigos de status de resposta HTTP. Os desenvolvedores de back-end, as operações de desenvolvimento e os engenheiros de serviço às vezes podem fornecer insights exclusivos sobre possíveis casos extremos que você não antecipou.
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 abaixo, 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, uma tentativa é feita para analisar o corpo da resposta como JSON, gerando 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ê precisa preparar seu código para receber vários 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 que é analisado com sucesso pelo método Response.json()
. Pode acontecer de o serviço ficar indisponível. Quando o tempo acabar, uma 500 Internal Server Error
será retornada. Se as técnicas de tratamento de erros adequadas não forem usadas durante a análise de JSON, isso poderá causar problemas na página para o usuário, porque um erro não tratado será gerado.
Quando a solicitação de rede precisa ser cancelada antes da conclusão
Este exemplo de código usa um AbortController
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 você pode precisar cancelar uma solicitação em andamento podem variar, mas dependem do seu caso de uso e do ambiente. O código abaixo demonstra como transmitir um AbortSignal
para a API Fetch. O AbortSignal
é anexado a um AbortController
, e o AbortController
inclui um método abort()
, que indica ao 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. Com relação a uma solicitação de busca, faça a si mesmo perguntas como:
- O que acontece se o servidor de destino cair?
- O que acontece se o Fetch receber uma resposta inesperada?
- O que acontece se a conexão de Internet do usuário falhar?
Dependendo da complexidade da sua página da Web, também é possível esboçar um fluxograma que descreve a funcionalidade e a interface do usuário para diferentes cenários.