如何使用 nestjs 处理猫鼬错误

Ryo*_*uki 11 typescript nestjs

我按照https://docs.nestjs.com/techniques/mongodb 中的示例进行操作

问题是出现猫鼬验证错误时(例如,我有一个带有必填字段的架构,但未提供):

来自 games.service.ts:

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

save() 函数返回一个 Promise。

现在我在 game.controller.ts 中有这个

  @Post()
  async create(@Body() createGameDto: CreateGameDto) {
    this.gamesService.create(createGameDto);
  }
Run Code Online (Sandbox Code Playgroud)

处理错误然后返回具有不同 http 状态和 json 文本的响应的最佳方法是什么?你通常会抛出一个HttpException但从哪里?如果我在承诺中使用 .catch() 处理错误,我就不能这样做。

(刚开始使用nestjs框架)

1Fp*_*x6k 9

首先,您忘记return在控制器中添加create 方法。这是一个常见的、非常具有误导性的错误,我犯了上千次并花了我几个小时来调试。

要捕获异常:

您可以尝试使用@Catch.

对于我的项目,我正在执行以下操作:

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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以在你的控制器中像这样使用它(或者甚至将它用作全局/类范围的过滤器):

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

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

(在 findAll() 调用中,重复异常在这里没有意义,但您明白了)。

此外,我强烈建议使用类验证器,如下所述:https : //docs.nestjs.com/pipes

  • 对我来说,这个解决方案不起作用。我有完全相同的设置,除了控制器异步方法是对在 mongodb 上执行 .save() 的服务的调用。自定义 MongoExceptionFilter 不会触发。我猜 `MongoError` 不会被“捕获”,因为当我将 Catch 留空时它会触发... "@nestjs/core": "^5.4.0", "@nestjs/mongoose": "^5.2 .2", "猫鼬": "^5.4.7", (2认同)

Ric*_*gis 8

您可以使用错误的猫鼬和添加它AllExceptionFilter

有关异常过滤器,请参阅 NestJS 文档

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
  HttpStatus,
  InternalServerErrorException
} from "@nestjs/common";

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: InternalServerErrorException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();

    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    /**
     * @description Exception json response
     * @param message
     */
    const responseMessage = (type, message) => {
      response.status(status).json({
        statusCode: status,
        path: request.url,
        errorType: type,
        errorMessage: message
      });
    };

    // Throw an exceptions for either
    // MongoError, ValidationError, TypeError, CastError and Error
    if (exception.message.error) {
      responseMessage("Error", exception.message.error);
    } else {
      responseMessage(exception.name, exception.message);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

您可以像这样将它添加到 main.ts 中,但这实际上取决于您的用例。您可以在 Nest.js文档中查看它。

async function bootstrap() {

  const app = await NestFactory.create(AppModule);

  app.useGlobalFilters(new AllExceptionsFilter());

  await app.listen(3000);
}
bootstrap();
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你。


BoS*_*kiv 8

今天钉钉子

验证错误.filter.ts:

import { ArgumentsHost, Catch, RpcExceptionFilter } from '@nestjs/common';
import { Error } from 'mongoose';
import ValidationError = Error.ValidationError;

@Catch(ValidationError)
export class ValidationErrorFilter implements RpcExceptionFilter {

  catch(exception: ValidationError, host: ArgumentsHost): any {

    const ctx = host.switchToHttp(),
      response = ctx.getResponse();

    return response.status(400).json({
      statusCode: 400,
      createdBy: 'ValidationErrorFilter',
      errors: exception.errors,
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

主要.ts:

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationErrorFilter } from './validation-error.filter';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalFilters(new ValidationErrorFilter());
  await app.listen(process.env.PORT || 3000);
}
bootstrap();
Run Code Online (Sandbox Code Playgroud)

结果:

{
  "statusCode": 400,
  "createdBy": "ValidationErrorFilter",
  "errors": {
    "dob": {
      "properties": {
        "message": "Path `dob` is required.",
        "type": "required",
        "path": "dob"
      },
      "kind": "required",
      "path": "dob"
    },
    "password": {
      "properties": {
        "message": "Path `password` is required.",
        "type": "required",
        "path": "password"
      },
      "kind": "required",
      "path": "password"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

10696 次

最近记录:

5 年 前