• 使用 NestJs 进行错误处理


    使用 NestJs 进行错误处理

    API 错误处理是软件开发的一个重要方面,包括 API 设计和实现。它涉及捕获和处理 API 请求处理过程中引发的错误,并将其转换为适当且有意义的 HTTP 响应,然后发送回客户端。

    这是 API 开发中常见的做法,因为它为 API 的使用者提供了一致且用户友好的体验。它确保客户端始终收到信息丰富且可操作的错误响应,而不是通用错误消息。

    精心设计的 API 错误处理有助于提高 API 的稳定性、安全性和可用性。

    express示例

    为了说明错误处理的重要性及其解决的问题,让我们看看一个简单的express示例。

    const express = require('express');
    const app = express();
    
    // ...
    
    app.get('/users/:id', async (req, res) => {
      const { id } = req.params;
      const user = await getUserById(id);
    
      if (!user) {
        res.status(404).json({ error: 'User not found' });
      } else {
        res.json(user);
      }
    });
    
    // ...
    
    app.listen(3000, () => {
      console.log('Server is running on port 3000');
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    这段代码展示了错误处理背后的想法。它基本上说:如果找到用户,则返回 200 HTTP 代码,如果没有,则返回带有状态代码 404 的错误消息。

    但是,当我们开始处理大量请求以及可能出现的不同错误情况时,这种处理控制器内部错误的方法开始变得越来越困难,特别是在标准化.。这时候错误处理策略就派上用场了。

    使用Next处理错误

    虽然 Express 有解决这个问题的方法,但我们在这里将重点讨论 NestJs 如何解决它以及我们如何利用它。

    Nest带有内置的异常处理机制。这意味着每次 API 中抛出异常时,Nest 都会自动捕获它并转换为对客户端的良好响应。

    import { Controller, Get, Param } from '@nestjs/common';
    import { UserService } from './user.service';
    
    @Controller('users')
    export class UserController {
      constructor(private readonly userService: UserService) {}
    
      @Get(':id')
      async getUser(@Param('id') id: string) {
        return this.userService.getUser(id);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    import { Injectable, NotFoundException } from '@nestjs/common';
    import { UserRepository } from './user.repository';
    import { User } from './user.entity';
    
    @Injectable()
    export class UserService {
      constructor(private readonly userRepository: UserRepository) {}
    
      async getUser(id: string): Promise<User> {
        const user = await this.userRepository.findOne(id);
    
        if (!user) {
          throw new NotFoundException('User not found');
        }
    
        return user;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    请注意,错误可能会在服务内部抛出,Nest 将负责捕获该错误并指定将发送到客户端的响应。在这种情况下,我们不需要指定控制器如何根据服务的行为进行操作,它只负责接收 HTTP 请求并将其路由到适当的服务。

    如果找不到用户,客户端将收到类似以下内容的信息:

    {
      "statusCode": 404,
      "message": "User not found",
      "error": "Not Found"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    自定义异常响应

    NestJS 异常过滤器是允许您拦截和处理应用程序中引发的异常的组件。它们提供了一种将异常转换为特定响应或根据异常的类型或上下文执行自定义操作的机制。

    Nest 捕获异常时,我们将使用此解决方案自定义我们的响应。提供的示例是一个简单的用例,我们可以根据自己的情况添加更多逻辑。

    这样做实际上非常简单。首先我们创建一个`http-exception.filter.ts``文件:

    import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
    import { Request, Response } from 'express';
    
    @Catch(HttpException)
    export class HttpExceptionFilter implements ExceptionFilter {
        catch(exception: HttpException, host: ArgumentsHost) {
            const ctx = host.switchToHttp();
            const response = ctx.getResponse<Response>();
            const request = ctx.getRequest<Request>();
            const status = exception.getStatus();
    
            response
                .status(status)
                .json({
                    statusCode: status,
                    message: exception.message,
                    timestamp: new Date().toISOString(),
                    path: request.url,
                });
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    分解一下:

    • 过滤器旨在处理HttpException类型的异常。
    • 当应用程序中抛出HttpException类型的异常时,将执行此过滤器的catch()方法。
    • catch()方法内部,我们从异常和请求对象中提取必要的信息。
      然后,过滤器使用response.status()来设置响应中的 HTTP 状态码。它构建一个 JSON 响应,其中包含我发现与客户端相关的属性,并且可以根据自己的需要进行更改。
    • 过滤器将使用 response.json() 方法将响应发送到客户端。

    最后,我们需要通过将以下内容添加到main.ts文件中来告诉 Nest 应用程序使用此过滤器:

    async function bootstrap() {
        const app = await NestFactory.create(AppModule);
    
        // ...
    
        // add the following line
        app.useGlobalFilters(new HttpExceptionFilter());
    
        // ...
    
        await app.listen(configService.get('app.port') || 8080);
    }
    
    bootstrap();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    现在,每当应用程序中抛出HttpException异常时,客户端都会收到带有相关错误详细信息的 JSON 响应,包括状态代码、消息、时间戳和请求路径。这允许在整个应用程序中实现一致且标准化的错误处理和响应格式。

  • 相关阅读:
    大语言模型LLM微调技术深度解析:Fine-tuning、Adapter-Tuning与Prompt Tuning的作用机制、流程及实践应用(LLM系列08)
    学会这个样生成性能测试报告,拿下20k轻轻松松
    【JUC系列-06】深入理解Semaphore底层原理和基本使用
    Linux之iostat溯源diskstats
    中小企业是否需要微软活动目录联合服务(ADFS)?
    1412. 查找成绩处于中游的学生
    ContentType:application/x-www-form-urlencoded请求方法遇到的坑【PHP】
    HTML5表单验证
    Soul CEO张璐团队优化治理平台安全生态,构建健康社交秩序
    MySQL | 查询接口性能调优、编码方式不一致导致索引失效
  • 原文地址:https://blog.csdn.net/qq_42880714/article/details/134485421