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)
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
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);
}
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