[ad_1]
Introdução
Exceções e erros podem ocorrer enquanto os usuários interagem com qualquer aplicativo, cabe aos engenheiros de software escolher um meio para lidar com qualquer erro que possa surgir – consciente ou inconscientemente. Como resultado, os desenvolvedores de back-end que constroem APIs com o Express trabalham para garantir que estejam criando uma API útil, eficiente e utilizável. O mais importante é lidar com os erros de forma a construir um sistema robusto, pois isso ajuda a reduzir o tempo de desenvolvimento, erros absolutos, problemas de produtividade e determina o sucesso ou a escalabilidade do desenvolvimento de software.
Você precisa registrar a mensagem de erro, suprimir o erro, notificar os usuários sobre o erro ou escrever código para lidar com erros? Não me pergunte mais.
Neste guia, aprenderemos como criar uma base de código robusta de tratamento de erros para aplicativos Express, que servirá para ajudar a detectar erros de aplicativos e tomar ações ideais para recuperar qualquer aplicativo de falha normal durante o tempo de execução.
Observação: Usaremos o Postman para testar a API em nossa demonstração. Você pode baixá-lo na página de download do Postman. Como alternativa, você pode simplesmente usar o navegador, a linha de comando curl
ou qualquer outra ferramenta com a qual você esteja familiarizado.
O que é Tratamento de Erros?
No desenvolvimento de software, existem dois tipos diferentes de exceções: operacional e programático.
- Falhas operacionais podem surgir durante o tempo de execução e, para evitar que o aplicativo seja encerrado abruptamente, devemos lidar com essas exceções com eficiência por meio de métodos eficientes de tratamento de erros.
- Exceções programáticas são lançadas manualmente por um programador, quando surge um estado excepcional.
Você pode pensar em exceções operacionais como exceções “inesperadas, mas previstas” (como acessar um índice fora dos limites) e exceções programáticas como exceções “esperadas e previstas” (como uma exceção de formatação de número).
O tratamento de exceções é o procedimento usado para encontrar e corrigir falhas em um programa. O tratamento de erros envia mensagens que incluem o tipo de erro ocorrido e a pilha onde ocorreu o erro.
Observação: Na ciência da computação, as exceções são recuperáveis e geralmente decorrem de problemas operacionais ou programáticos durante o tempo de execução. Erros geralmente surgem de fatores externos, como limitações de hardware, problemas com conectividade, falta de memória, etc. Em JavaScript, os termos são muitas vezes usados de forma intercambiável e exceções personalizadas são derivadas do Error
classe. o Error
A própria classe representa erros e exceções.
No Express, o tratamento de exceções refere-se a como o Express se configura para capturar e processar exceções síncronas e assíncronas. A vantagem do tratamento de exceções no Express é que, como desenvolvedor, você não precisa escrever seus próprios manipuladores de exceção; O Express vem com um manipulador de exceção padrão. O manipulador de exceção ajuda a identificar erros e relatá-los ao usuário. Ele também fornece várias estratégias corretivas e as implementa para mitigar exceções.
Embora isso possa parecer um monte de coisas ocultas, o tratamento de exceções no Express não retarda o processo geral de um programa ou interrompe sua execução.
Compreendendo o tratamento de exceções no Express
Com o manipulador de erros padrão que vem com o Express, temos em mãos um conjunto de funções de middleware que ajudam a detectar erros em manipuladores de rotas automaticamente. Em breve, criaremos um projeto para colocar em prática a teoria de como retornar os devidos erros em um app Express e como não vazar informações sigilosas.
Definindo a função de middleware no Express
As funções de middleware de tratamento de erros são definidas de tal forma que aceitam um Error
object como o primeiro parâmetro de entrada, seguido pelos parâmetros padrão de qualquer outra função de middleware: request
, response
e next
. o next()
A função pula todo o middleware atual para o próximo manipulador de erros do roteador.
Configurando o tratamento de erros no Express
Execute o seguinte comando em seu terminal para criar um aplicativo Node and Express:
$ mkdir error-handling-express
Na pasta recém criada, vamos inicializar um novo projeto Node:
$ cd error-handling-express && npm init -y
Isso cria um package.json
arquivo em nossa pasta.
Para criar um servidor Express em nosso aplicativo Node, precisamos instalar o express
pacote, dotenv
para carregar automaticamente variáveis de ambiente em .env
arquivo em process.env
objeto, e nodemon
para reiniciar o aplicativo do nó se uma alteração de arquivo for observada no diretório.
$ npm install express dotenv nodemon
A seguir, crie um app.js
arquivo na pasta do projeto que servirá como arquivo de índice para o aplicativo.
Agora que instalamos todas as dependências necessárias para nosso aplicativo Express, precisamos configurar o script para ler o aplicativo no package.json
Arquivo. Para conseguir isso, o package.json
arquivo, para que o scripts
objeto é como mostrado abaixo:
"scripts": {
"start": "nodemon app.js"
},
Como alternativa, você pode pular usando nodemon
E use node app.js
em vez de.
Configurando um servidor Express
Para configurar o servidor, primeiro temos que importar os vários pacotes para app.js
. Também criaremos um .env
arquivo no diretório do projeto – para armazenar todas as variáveis de ambiente para o aplicativo:
const express = require('express')
require('dotenv').config
PORT=4000
Definimos o número da porta para o aplicativo em .env
que é carregado e lido por dotenv
e pode ser acessado posteriormente.
Inicializando o Express Server
Agora, precisamos inicializar o servidor Express e fazer nosso aplicativo escutar o número da porta do aplicativo, junto com uma solicitação para uma rota de teste – /test
. vamos atualizar app.js
abaixo das instruções de importação:
const app = express();
const port = process.env.PORT || 4000;
app.get("/test", async (req, res) => {
return res.status(200).json({ success: true });
});
app.listen(port, () => {
console.log(`Server is running at port ${port}`);
});
A partir daqui, aprenderemos como lidar com vários casos de uso de erros operacionais que podem ser encontrados no Express.
Tratamento de erros não encontrados no Express
Suponha que você precise buscar todos os usuários de um banco de dados de usuários; try/catch
bloco – na esperança de pegar qualquer erro que possa se projetar no catch
quadra:
const getUser = () => undefined;
app.get("/get-user", async (req, res) => {
try {
const user = getUser();
if (!user) {
throw new Error('User not found');
}
} catch (error) {
console.log(error);
res.status(400).send(error.message)
}
return res.status(200).json({
success: true
});
});
Isto resulta em:
User not found
Agora, quando essa solicitação é feita (você pode testar usando o Postman) e não existe nenhum usuário no banco de dados, o cliente recebe uma mensagem de erro que diz “Usuário não encontrado”. Além disso, você notará que o erro também está registrado no console.
Otimizando o Tratamento de Erros com o Middleware do Manipulador de Erros
Podemos otimizar o desenvolvimento criando um middleware de tratamento de erros que viria no final de todas as rotas definidas, para que, se um erro for lançado em uma das rotas, o Express automaticamente dê uma olhada no próximo middleware e continue descendo a lista até atingir o manipulador de erros. O manipulador de erros processará o erro e também enviará uma resposta ao cliente.
Confira nosso guia prático e prático para aprender Git, com as melhores práticas, padrões aceitos pelo setor e a folha de dicas incluída. Pare de pesquisar comandos do Git no Google e, na verdade, aprender isto!
Para começar, crie uma pasta chamada middleware
no diretório do projeto, e nesta pasta, crie um arquivo chamado errorHandler.js
que define o manipulador de erros:
const errorHandler = (error, req, res, next) => {
console.log(error);
res.status(400).send(error.message);
}
module.exports = errorHandler;
Em nossa função de middleware, informamos ao Express que esta não é uma função básica de middleware, mas um manipulador de erros, adicionando o error
parâmetro antes dos 3 parâmetros básicos.
Agora, usaremos o manipulador de erros em nossa demonstração app.js
e lide com o erro inicial de busca de usuários com o middleware de tratamento de erros, conforme mostrado abaixo:
const getUser = () => undefined;
app.get("/get-user", async (req, res, next) => {
try {
const user = getUser();
if (!user) {
throw new Error("User not found");
}
} catch (error) {
return next(error);
}
});
app.use(errorHandler);
Podemos otimizar ainda mais nosso código, criando uma abstração em torno do try/catch
lógica. Podemos conseguir isso criando uma nova pasta no diretório do projeto chamada utils
e nele, crie um arquivo chamado tryCatch.js
.
Para abstrair o try-catch
lógica – podemos definir uma função que aceita outra função (conhecida como controlador) como seu parâmetro e retorna um async
função que manterá um try/catch
para qualquer controlador recebido.
Se ocorrer um erro no controlador, ele é detectado no catch
bloco e a próxima função é chamada:
const tryCatch = (controller) => async (req, res, next) => {
try {
await controller(req, res);
} catch (error) {
return next(error);
}
};
module.exports = tryCatch;
Com o try/catch
abstração, podemos refatorar nosso código para torná-lo mais sucinto pulando o try-catch
cláusula explicitamente ao buscar usuários no app.js
:
const getUser = () => undefined;
app.get(
"/get-user",
tryCatch(async (req, res) => {
const user = getUser();
if (!user) {
throw new Error("User not found");
}
res.status(400).send(error.message);
})
);
Abstraímos com sucesso a lógica try-catch e nosso código ainda funciona como antes.
Lidando com erros de validação no Express
Para esta demonstração, criaremos uma nova rota em nosso aplicativo Express para login – para validar um ID de usuário no login. Primeiro, instalaremos o joi
pacote, para ajudar na criação de um esquema, com o qual podemos impor requisitos:
$ npm i joi
Em seguida, crie um esquema que é um Joi.object
com um userId
que deve ser um número e é obrigatório – o que significa que a solicitação deve corresponder a um objeto com um ID de usuário nele.
Podemos usar o validate()
no objeto do esquema para validar cada entrada no esquema:
const schema = Joi.object({
userId: Joi.number().required(),
});
app.post(
"/login",
tryCatch(async (req, res) => {
const {error, value} = schema.validate({});
if (error) throw error;
})
);
Se um objeto vazio for passado para o validate()
método, o erro seria tratado normalmente e a mensagem de erro seria enviada ao cliente:
No console, também temos acesso a um details
array que inclui vários detalhes sobre o erro que podem ser comunicados ao usuário, se necessário.
Para lidar especificamente com erros de validação de forma a passar os detalhes de erro apropriados por erro de validação, o middleware do manipulador de erros pode ser refatorado:
const errorHandler = (error, req, res, next) => {
console.log(error);
if (error.name === "ValidationError") {
return res.status(400).send({
type: "ValidationError",
details: error.details,
});
}
res.status(400).send(error.message);
};
module.exports = errorHandler;
Com errorHandler.js
agora customizado, quando fazemos a mesma requisição com um objeto vazio passado para o validate()
método:
Agora temos acesso a um objeto customizado que retorna mensagens de forma mais legível/amigável. Dessa forma, somos capazes de enviar e lidar com diferentes tipos de erros com base no tipo de erro recebido.
Conclusão
Neste guia, analisamos todos os aspectos do tratamento de erros do Express.js, incluindo como o código síncrono e assíncrono é tratado por padrão, como criar suas próprias classes de erro, como escrever funções de middleware de tratamento de erros personalizadas e fornecer next
como o manipulador de captura final
Como acontece com todas as tarefas, também existem práticas recomendadas durante o desenvolvimento, que incluem tratamento eficaz de erros, e hoje aprendemos como podemos lidar com erros em um aplicativo Express de maneira robusta.
Lidar com erros adequadamente não significa apenas reduzir o tempo de desenvolvimento ao encontrar bugs e erros facilmente, mas também desenvolver uma base de código robusta para aplicativos de grande escala. Neste guia, vimos como configurar o middleware para lidar com erros operacionais. Algumas outras maneiras de melhorar o tratamento de erros incluem: não enviar rastreamentos de pilha, interromper processos normalmente para lidar com exceções não capturadas, fornecer mensagens de erro apropriadas, enviar logs de erro e configurar uma classe que estenda o Error
classe.
Espero que os exemplos que usei neste tutorial tenham sido agradáveis para você. Cobri vários cenários que você poderia encontrar ao escrever um aplicativo Express para uso no mundo real sobre gerenciamento de erros. Por favor, deixe-me saber se há alguma coisa que eu perdi. Isso nos beneficiará e também me ajudará a aprender mais. Tenha um bom dia e obrigado por ler.
Você pode consultar todo o código-fonte usado no artigo no Github.
Recursos adicionais
[ad_2]
Source link