mongoose 我无法正确处理NestJ中的异常

6jjcrrmo  于 2023-02-19  发布在  Go
关注(0)|答案(1)|浏览(146)

我正在尝试通过创建一个CRUD API来学习NestJs。我已经创建了我的控制器,模块,服务等等...
并且创建了一个get users/id端点。一切都运行良好,我决定增加一些安全性。我想检查id是否不为空并且是一个字符串。如果不是,我想抛出一个异常(坏请求)+ console.log一条消息。我还想检查当我用一个好的if查找用户时,该用户是否存在。如果不是,抛出一个未找到异常。
以下是我的服务:

async findOne(id: string): Promise<IUser | null> {
    if (id === null || typeof id !== 'string') {
      throw new BadRequestException('Id must be a string');
    }
    const user = await this.userModel.findById(id).exec();
    if (user === null) {
      throw new NotFoundException('No user found for this id');
    }
    return user;
  }

和控制器:

@Get(':id')
  async find(@Param('id') id: string) {
    try {
      return await this.userService.findOne(id);
    } catch (error) {
      if (error instanceof BadRequestException) {
        throw new HttpException(
          {
            status: HttpStatus.FORBIDDEN,
            error: 'This is a custom message',
          },
          HttpStatus.FORBIDDEN,
          {
            cause: error,
          },
        );
      } else if (error instanceof NotFoundException) {
        throw new HttpException(
          {
            status: HttpStatus.NOT_FOUND,
            error: 'This is a custom not found message',
          },
          HttpStatus.NOT_FOUND,
          {
            cause: error,
          },
        );
      }
    }
  }

问题是当我尝试使用.../users/1111发出get请求时,我得到了200响应,而当我尝试使用一个好的id(字符串)但没有用户链接时,我也得到了200响应。
我不明白为什么...你能帮帮我吗?我也想把留言记录下来。
你有什么建议吗?是正确的方式(标准+优雅)做?
谢谢你们)

nxagd54h

nxagd54h1#

在您的代码中,您正在检查id是否为string类型且不为null。从技术上讲,任何param都是string,因此即使1111也会变为"1111"。您可以通过将其记录为console.log({ id })来验证这一点(预期结果:{ id: "1111" })。
对于验证,我建议遵循有关验证管道的文档:NestJS documentation.

    • TLDR;**以下代码将添加一个全局管道以验证有效负载app.module.ts(从NestJS复制|管道)
import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_PIPE,
      useClass: ValidationPipe,
    },
  ],
})
export class AppModule {}

要使其工作,您需要安装class-validatorclass-transformer,因此运行:

npm i --save class-validator class-transformer

然后声明一个将用作DTO(数据传输对象)蓝图的类,如下所示:

import { IsString, IsNotEmpty } from 'class-validator';

export class IdDto {
  @IsNotEmpty()
  @IsString()
  id: string;
}

然后在控制器中使用IdDto

@Get(':id')
  async find(@Param() { id }: IdDto) {
    ...

这已经足够进行基本的验证了。此外,这会将有效负载转换为您期望的格式(或者失败并抛出验证错误)。这是通过从class-transformer公开的plainToClass方法完成的。因此,对于"1" + 1 = "11"这样的JavaScript类型强制不会有任何意外。
如果你需要格式化你的异常(或者用额外的数据来丰富它们),你可以使用异常过滤器。在官方文档中有一个关于它的很好的文档。
希望能有所帮助!

相关问题