How to handle mongoose error with nestjs

别来无恙 提交于 2019-12-08 04:57:13

问题


I followed the example from https://docs.nestjs.com/techniques/mongodb

The issue is when there is a mongoose validation error (e.g i have a schema with a required field and it isn't provided):

From games.service.ts:

  async create(createGameDto: CreateGameDto): Promise<IGame> {
    const createdGame = new this.gameModel(createGameDto);
    return await createdGame.save();
  }

The save() function returns a Promise.

Now i have this in the game.controller.ts

  @Post()
  async create(@Body() createGameDto: CreateGameDto) {
    this.gamesService.create(createGameDto);
  }

What is the best way to handle an error and then return a response with a different http status and maybe a json text? You would usually throw a HttpException but from where? I can't do that if i handle the errors using .catch() in the promise.

(Just started using the nestjs framework)


回答1:


First, you forgot to add return in your create method inside the controller. This is a common, very misleading mistake I made a thousand of times and took me hours to debug.

To catch the exception:

You could try to catch MongoError using @Catch.

For my projects I'm doing the following:

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

@Catch(MongoError)
export class MongoExceptionFilter implements ExceptionFilter {
  catch(exception: MongoError, host: ArgumentsHost) {
    switch (exception.code) {
      case 11000:
        // duplicate exception
        // do whatever you want here, for instance send error to client
    }
  }
}

You can then just use it like this in your controller (or even use it as a global / class scoped filter):

import { MongoExceptionFilter } from '<path>/mongo-exception.filter';

@Get()
@UseFilters(MongoExceptionFilter)
async findAll(): Promise<User[]> {
  return this.userService.findAll();
}

(Duplicate exception doesn't make sense here in a findAll() call, but you get the idea).

Further, I would strongly advise to use class validators, as described here: https://docs.nestjs.com/pipes




回答2:


use try/catch

async getUser(id: string, validateUser ?: boolean): Promise<Users> {
    try {
      const user = await this.userModel.findById(id).exec();
      if(!user && validateUser) {
        throw new UnauthorizedException();
      }else if(!user) {
        throw new HttpException(`Not found this id: ${id}`, HttpStatus.NOT_FOUND)
      }
      return user;
    } catch (err) {
      throw new HttpException(`Callback getUser ${err.message}`, HttpStatus.BAD_REQUEST);
    }



回答3:


What I am doing in my application is to use Exception Filters (https://docs.nestjs.com/exception-filters) and try/catch:

  async create(createGameDto: CreateGameDto): Promise<IGame> {
    try {
      const createdGame = new this.gameModel(createGameDto);
      return await createdGame.save();
    } catch (e) {
       // the e here would be MongoError
       throw new InternalServerException(e.message);
    }
  }


来源:https://stackoverflow.com/questions/50864001/how-to-handle-mongoose-error-with-nestjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!