当前位置: 首页 > 知识库问答 >
问题:

类型安全类型异常错误处理

翟展
2023-03-14

我想使用MongoDB用NestJs和TypeORM创建一个应用程序。假设我有一个实体,除了ID字段外,还有两个唯一的字段

@Entity()
export class Module extends BaseEntity {
  @ObjectIdColumn()
  public id: ObjectID;

  @Column({ unique: true })
  public moduleName: string;

  @Column({ unique: true })
  public displayName: string;
}

当我想用已经存在的moduleNamedisplayName创建一个新模块时,我得到了以下异常错误

[Nest] 6624   - 2020-02-20 16:31:36   [ExceptionsHandler] E11000 duplicate key error collection: test-mongo.module index: UQ_61128bd419e3c3a6d8d7d565ed9 dup key: { moduleName: "firstModule" } +23849ms
BulkWriteError: E11000 duplicate key error collection: test-mongo.module index: UQ_61128bd419e3c3a6d8d7d565ed9 dup key: { moduleName: "firstModule" }
    at OrderedBulkOperation.handleWriteError (C:\Users\mhermsen\Gitlab Repositories\server\node_modules\mongodb\lib\bulk\common.js:1210:11)
    at resultHandler (C:\Users\mhermsen\Gitlab Repositories\server\node_modules\mongodb\lib\bulk\common.js:519:23)
    at C:\Users\mhermsen\Gitlab Repositories\server\node_modules\mongodb\lib\core\connection\pool.js:404:18
    at processTicksAndRejections (internal/process/task_queues.js:76:11)

因此,在catch语句中,我必须处理传入的错误。我要做的是

try {
  // create module
} catch (error) {
  if (/* error is TypeORM error */) {
    if (/* wrong attribute is the module name */) {
      // module name exists ...
    }

    if (/* wrong attribute is the display name */) {
      // display name exists ...
    }
  }
}

TypeORM是否公开预制异常?是否有我可以使用的枚举?获取这些TypeORM数据库错误的好方法是什么?

这里似乎列出了一些错误

https://github.com/typeorm/typeorm/tree/master/src/error

但我无法导入它们,也没有找到有关BulkWriteError

在我的声明中,有可能做这样的事情

const code: number = error.code;

if (code === 11000) {
  throw new ConstraintException(error.errmsg);
}

throw error;

但是你知道这不是最好的方法。此外,此错误对象不会告诉我moduleNamedisplayName是否无效。一触即发

errmsg:'E11000重复密钥错误集合:test mongo。模块索引:UQ_61128bd419e3c3a6d8d7d565ed9 dup键:{moduleName:“firstModule”},

我必须创建自己的从这些错误代码到异常的映射吗?

共有1个答案

袁宜民
2023-03-14

我不确定你是否找到了答案,但这里有一个替代方法,我使用。无论数据库类型是什么,这都是有效的。

我尝试在调用数据库服务时使用自定义装饰器捕捉异常(任何类似于这样的crud操作)

所以这里是我的自定义装饰器(函数装饰器。您可以选择装饰器的类型。它也可以是类装饰器)

目标:-当前对象的原型

属性:-方法的名称

描述符:-方法即对象的属性描述符。GetOwnProperteDescriptor

注意:Nestjs的当前实现方式与swagger的实现方式相同——如果方法的args/返回值发生更改,则不会使用正确的响应对象呈现swagger API部分。因此使用代理的概念来改变行为

export const DatabaseFailureHandler = (target: any, property: string, descriptor: PropertyDescriptor): any => {
  const className = target.constructor.name;
 // 
  const original = descriptor.value;

  let customException;
  // const proxyHandlerFn = function(target, )
  descriptor.value = new Proxy(original, {
    apply: async function(target, thisArg, args) {
      console.log(`Call with args: ${args} -------${className}#`);
      let result;
      try {
        result = await target.apply(thisArg, args);
        console.log('result in databasefailure handling"', result);
        //WARNING!!! - Test only
        // throw new Error('DatabaseException');
        return result;
      } catch (err) {
        // TODO: Replace with the actual logger with the logs of service and class names
        console.log('err capt:', err);

// Below is my custom exception implementation that has my required details. You can 
 //modify it to have the className, methodName args, etc...
        customException = new AppConfigService(new AppUtilService()).retrieveCustomHttpException(
          HttpStatus.INTERNAL_SERVER_ERROR,
          MATRIX_API.ERROR_MSG.DATABASE_ERROR + `:${err.name}`,
          err,
          HttpStatus.INTERNAL_SERVER_ERROR.toString(),
          MATRIX_API.DATABASE.ERR_TYPE.DATABASE_EXCEPTION_ERR_TYPE,
          err.message
        );
        throw customException;
      }
    }
  });
};

现在在我的service.ts中实现了像这样的自定义装饰器

@DatabaseFailureHandler
  async updateXXXXSkill(
    corpId: string,
    skillId: number,
    skillUpdate: UpdateRequestModel
  ): Promise<UpdateResponseModel> {
// Either get the repo from connection or entity manager or Inject them if TypeORMModule is used
    const entity: Employee = this.repository.create({
      ...skillUpdate,
      corpId,
      skillId
    });
    await this.repository.update(
      {
        corpId,
        skillId
      },
      entity
    );
    return XXXXX;
  }

希望这种方法能够让您捕获所有错误详细信息,并通过自定义异常过滤器抛出它们。这是我编写的用于捕获任何异常的集中式过滤器。它是在服务器的开始处注册的。您可以遵循官方的nestjs文档

 类似资料:
  • 问题内容: 我之前从未遇到过此错误,所以我不确定该怎么做或意味着什么 未处理的异常类型 它在以下代码中发生: 它给了我2个选项“添加抛出声明”和“使用try / catch进行环绕”。 我该怎么办,为什么? 问题答案: 这意味着您要调用的方法已使用指令声明了从类派生的异常。当以这种方式声明一个方法时,您将被迫使用一个块来处理该异常,或者将一个相同的(对于相同的异常或超类型)语句添加到您的方法声明中

  • 我在我的项目中使用Gson。但它返回给我错误 我得到一个服务器响应,如下所示 我有一个错误,需要一个字符串,但是BEGIN_OBJECT 我应该如何处理这个异常?? 我没有访问数据库的权限,因为我使用API

  • 我是Flutter的新手,试图验证用户,但我面临一个错误,即使在终端中接收到响应状态200,因此我无法导航到授权页面。 请问有人能帮我吗? 登录-屏幕代码: 登录api代码: 类用户信息: 带json的邮递员:我的json 错误:终端错误 非常感谢!!

  • 我正在开发我的flutter应用程序的身份验证。请帮我解决这个问题。我无法识别返回这样一个错误的问题,声明未处理异常:类型列表不是类型字符串的子类型。 以下是登录屏幕的代码: 执行登录的上述代码部分: 错误

  • 更新:感谢@Rjulcaa回答我的地图现在是一个列表,但是列表没有显示在用户界面上。我转过来,我需要用FutureBuilder来处理未来,所以如果有人面临这个问题,记得在你的用户界面主体中添加一个FutureBuilder,并在构建器上返回你想要显示的小部件。 我正在制作一个todo列表教程,我正在尝试添加JSON上的编码功能,我的todoList将其保存在SharedReferences上,当