Como usar filtros de exceção Nest.js para lidar com erros
Exceções não tratadas podem causar confusão e frustração. Limpe-os com filtros de exceção.
Os filtros de exceção Nest.js fornecem uma maneira de interceptar e tratar exceções globalmente ou por controlador.
Eles permitem centralizar a lógica de tratamento de erros, formatar respostas de erros e fornecer tratamento de erros consistente em todo o seu aplicativo. Saiba mais sobre filtros de exceção e como usá-los para lidar adequadamente com erros de aplicativos.
Tratamento de erros padrão em Nest.js
Por padrão, Nest.js tem uma camada de exceção que lida com quaisquer exceções que o código do seu aplicativo não suporta.
Quando ocorre um erro não tratado em seu aplicativo, o Nest.js o detecta e retorna um erro interno do servidor 500 ao cliente. O JSON que Nest.js retorna neste caso é assim:
{
"statusCode": 500,
"message": "Internal server error"
}
Se o objeto de erro gerado pelo seu código contiver um statusCode e uma mensagem, o Nest.js retornará esses valores em vez da resposta padrão.
Para evitar esse comportamento genérico e enviar uma resposta de erro mais significativa ao cliente, você precisa lidar diligentemente com todos os erros que possam ocorrer em seu aplicativo. Você pode conseguir isso usando os filtros de exceção integrados ou personalizados do Nest.js.
Criando um filtro de exceção personalizado
Para demonstrar o processo de criação de um filtro de exceção personalizado, tente criar um que lide com todas as exceções HTTP.
Comece com um arquivo chamado http.exception.ts e adicione as seguintes importações a ele:
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
Essas importações atendem aos seguintes propósitos.
- ExceptionFilter: Esta é uma interface que descreve a implementação de um filtro de exceção.
- Catch: Este é um decorador que marca uma classe como um filtro de exceção Nest.
- ArgumentsHost: Esta interface fornece métodos para recuperar os argumentos passados para um manipulador. Ele permite que você escolha o contexto de execução apropriado (por exemplo, HTTP, RPC ou WebSockets) do qual recuperar argumentos.
- HttpException: esta é uma classe que define a exceção HTTP base do Nest.
- Solicitação e Resposta: Estas são as interfaces para uma solicitação Express.js e um objeto de resposta, respectivamente.
A seguir, crie uma classe, HttpExceptionFilter, que implemente ExceptionFilter. Anote-o com o decorador Catch para indicar que ele trata HttpExceptions:
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {}
Em seguida, preencha a classe com este código:
catch(exception: HttpException, host: ArgumentsHost) {
// Get the response object from the arguments host
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
// Get the request object from the arguments host
const request = ctx.getRequest<Request>();
// Get the status code from the exception
const status = exception.getStatus();
// Send a JSON response using the response object
response.status(status).json({
statusCode: status,
timestamp: new Date().toISOString(),
path: request.url,
message:
exception.message
|| exception.getResponse()['message']
|| 'Internal Server Error',
});
}
Este bloco de código recupera os objetos de solicitação e resposta do objeto ArgumentsHost e extrai informações relevantes da exceção. Ele retorna uma resposta de objeto JSON estruturada, com detalhes sobre o erro, para o cliente.
Filtros de exceção de associação
Você pode vincular um filtro de exceção a um controlador ou a todo o aplicativo, dependendo de suas necessidades.
Para vincular um filtro de exceção globalmente, primeiro importe o filtro de exceção para o arquivo main.ts. Em seguida, passe uma instância do seu filtro de exceção para o método app.useGlobalFilters:
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { HttpExceptionFilter } from './exception/http.exception';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Bind filter to the application
app.useGlobalFilters(new HttpExceptionFilter());
await app.listen(4050);
}
bootstrap();
Para vincular uma exceção a um controlador, importe o decorador UseFilters e seu filtro de exceção. Anote sua classe de controlador com o decorador @UseFilters e passe uma instância do seu filtro de exceção como argumento para o decorador:
@Controller()
@UseFilters(new HttpExceptionFilter())
export class AppController {}
O local onde você vincula seu filtro determinará o escopo do tratamento de erros. Os filtros vinculados ao controlador atenderão apenas ao controlador ao qual você os vinculou, e os filtros vinculados ao aplicativo atenderão ao aplicativo inteiro.
Usando exceções integradas para gerar erros
Nest.js fornece classes de exceção integradas que você pode usar para gerar erros.
Por exemplo, você pode lançar erros de código de status 404 com a classe NotFoundException:
getUserById(id: number) {
const user = users.find((user) => user.id === id);
if (!user) {
throw new NotFoundException({
message: `User with id ${id} not found`,
});
}
}
Este bloco de código usa uma instrução condicional para verificar se o usuário determinado existe. Caso contrário, gera um erro 404 usando NotFoundException, passando uma mensagem como argumento.
Classes de exceção integradas comuns
Outras classes de exceção integradas incluem, mas não estão limitadas a, as seguintes.
- BadRequestException: lança uma exceção indicando uma solicitação incorreta com um código de status 400. Você pode usar esta exceção quando a solicitação do cliente for inválida ou malformada e o servidor não puder processá-la devido a um erro do cliente. Normalmente implica que o cliente precisa modificar a solicitação para torná-la válida.
- UnauthorizedException: lança uma exceção indicando acesso não autorizado com um código de status 401. Você pode usar essa exceção quando um usuário não estiver autenticado ou não tiver as permissões necessárias para acessar um recurso.
- ForbiddenException: lança uma exceção indicando acesso proibido com um código de status 403. Você pode usar essa exceção quando um usuário estiver autenticado, mas não autorizado a executar uma ação específica.
- RequestTimeoutException: lança uma exceção indicando que a solicitação expirou com um código de status 408. Você pode usar essa exceção quando um servidor encerra uma solicitação porque demorou muito para ser processada.
- ConflictException: lança uma exceção indicando um conflito com um código de status 409. Você pode usar essa exceção quando houver um conflito entre a solicitação do cliente e o estado atual do recurso, como ao tentar criar um recurso que já existe.
- InternalServerErrorException: lança uma exceção indicando um erro interno do servidor com um código de status 500. Você pode usar esta exceção quando ocorrer um erro inesperado no lado do servidor, indicando que o servidor não pode atender à solicitação devido a um problema interno.
Melhores práticas para tratamento de erros em Nest.js
Ao lidar com erros no Nest.js, certifique-se de usar filtros de exceção para capturar e tratar exceções globalmente ou por controlador. Você também pode criar filtros personalizados para tipos de exceção específicos.
Além disso, certifique-se de usar as classes de exceção integradas apropriadas para gerar erros adequados e significativos. Essas práticas podem melhorar significativamente a confiabilidade dos seus aplicativos Nest.js.