首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NestJs使用自定义筛选器和@Catch捕获MongoDB错误(MongoError)

NestJs使用自定义筛选器和@Catch捕获MongoDB错误(MongoError)
EN

Stack Overflow用户
提问于 2019-02-04 19:36:21
回答 1查看 3.5K关注 0票数 3

我正在使用NestJS创建一个使用MongoDB的自定义API。我有以下设置:

代码语言:javascript
复制
  // users.controller.ts

  @Post('sign-up')
  @UseFilters(MongoExceptionFilter)
  async signUp(@Body() createUserDto: CreateUserDto): Promise<any> {
    return await this.userService.signUp(createUserDto).catch(error => {
      throw new BadRequestException(error);
    });
  }
代码语言:javascript
复制
  // user.service.ts

  async signUp(createUserDto: CreateUserDto): Promise<User> {
  const createUser = new this.userModel(createUserDto);
    return await createUser.save();
  }
代码语言:javascript
复制
  // mongo-exception.filter.ts

  import { ArgumentsHost,Catch, ConflictException, ExceptionFilter } from '@nestjs/common';
  import { MongoError } from 'mongodb';

  @Catch(MongoError)
  export class MongoExceptionFilter implements ExceptionFilter {
    catch(exception: MongoError, host: ArgumentsHost) {
      console.log('>>>>>>>>>>>>>>>>>>>> exception: ', exception);
    }
  }
代码语言:javascript
复制
  // package.json
  "dependencies": {
    "@nestjs/common": "^5.4.0",
    "@nestjs/core": "^5.4.0",
    "@nestjs/jwt": "^0.2.1",
    "@nestjs/mongoose": "^5.2.2",
    "@nestjs/passport": "^5.1.0",
    "@nestjs/typeorm": "^5.2.2",
    "fancy-log": "^1.3.3",
    "mongoose": "^5.4.7",
    "nestjs-config": "^1.3.0",
    "passport": "^0.4.0",
    "passport-http-bearer": "^1.0.1",
    "passport-jwt": "^4.0.0",
    "reflect-metadata": "^0.1.12",
    "rimraf": "^2.6.2",
    "rxjs": "^6.2.2",
    "typeorm": "^0.2.12",
    "typescript": "^3.0.1",
    "util": "^0.11.1"
  },

现在,每当我对/注册路由进行POST调用时,应该在save()中调用user.service.ts。这一切都有效。接下来,当我再次发布/注册路由时,它应该会触发一个MongoDB错误,因为具有相同电子邮件地址的用户已经存在(电子邮件地址是唯一的,因此重复密钥)。我看到在.catch(err => ...);中记录错误时会抛出错误,但问题是定制的MongoExceptionFilter。我不会触发MongoError的。当我将@Catch()留空时,它确实会触发,但不能处理异常。

我做错了什么?由于我看到了this的帖子,并把它作为一个基础,我似乎无法让它发挥作用。这是猫鼬或NestJS的更新,为什么它不再起作用了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-04 20:02:54

这是因为您将所有错误转换为BadRequestExceptions,这样您的MongoExceptionFilter就不会负责;它将检查对BadRequestException返回false的instanceof MongoError

代码语言:javascript
复制
return await this.userService.signUp(createUserDto).catch(error => {
      throw new BadRequestException(error);
    });

这在运行异常筛选器之前发生;它们总是最后运行。

从控制器中删除.catch()。如果您确实希望将所有其他异常转换为BadRequestExceptions (400),则可以编写第二个异常筛选器,该过滤器处理MongoExceptionFilter未处理的所有异常:

代码语言:javascript
复制
@Catch()
export class BadRequestFilter implements ExceptionFilter {
  catch(exception: Error, host: ArgumentsHost) {
    const response = host.switchToHttp().getResponse();
    response.status(400).json({message: exception.message});
  }
}

代码语言:javascript
复制
@Catch(MongoError)
export class MongoFilter implements ExceptionFilter {
  catch(exception: MongoError, host: ArgumentsHost) {
    const response = host.switchToHttp().getResponse();
    if (exception.code === 11000) {
      response.status(400).json({ message: 'User already exists.' });
    } else {
      response.status(500).json({ message: 'Internal error.' });
    }
  }
}

然后将两者添加到控制器中(订单非常重要!):

代码语言:javascript
复制
@UseFilters(BadRequestFilter, MongoFilter)
async signUp(@Body() createUserDto: CreateUserDto): Promise<any> {
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54523160

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档