【问题标题】:do NestJs or TypeScript provide premade exceptions like 'KeyNotFoundException'NestJs 或 TypeScript 是否提供预制异常,例如“KeyNotFoundException”
【发布时间】:2020-05-31 16:11:44
【问题描述】:

我想创建一个 NestJs 后端并从一些 REST 端点开始,但以后也想支持 GraphQL。

假设我想按 id 删除用户。服务层通过检查已删除行的数量来了解该用户是否被删除。如果不为零,则该用户已被删除。如果为零,我想抛出“未找到异常”。

我知道 Nest 附带了一些预制的 http 异常 https://docs.nestjs.com/exception-filters#built-in-http-exceptions。但我不想在我的服务层中使用这些异常,因为我认为它们应该只在 HTTP 层(REST 控制器)中使用。

所以我创建了自己的异常

export class KeyNotFoundException extends Error {
  constructor(message: string) {
    super(message);
  }
}

并在我的服务层和存储库层中使用它们。

public async deleteUserById(id: number): Promise<void> {
  const deletedRows: number = await this.usersRepository.deleteUserById(id);

  if (deletedRows === 0) {
    // my custom exception
    throw new KeyNotFoundException(`User with Id ${id} not found`);
  }
}

如果错误不是KeyNotFoundException,控制器可以处理此异常并抛出 404 或 500

@Delete(':id')
public async deleteUserById(@Param('id', ParseIntPipe) id: number): Promise<void> {
  try {
    await this.usersService.deleteUserById(id);
  } catch (error) {
    // my custom Exception
    if (error instanceof KeyNotFoundException) {
      // premade NestJs exception will throw 404
      throw new NotFoundException(error.message);
    }

    // premade NestJs exception will throw 500
    throw new InternalServerErrorException();
  }
}

我对解决方案不满意,因为我一直将自定义异常转换为 NestJs HTTP 异常。也许服务可能会出现多个异常,我将不得不使用开关来检查正确的异常类型。

关于如何解决这个问题有更好的想法吗?

例如,C# 带有 KeyNotFoundException,但我认为对于 TypeScript,我必须创建自己的异常系统。

【问题讨论】:

  • 看看Exception filtersdocs.nestjs.com/exception-filters。您可以通过使用app.useGlobalFilters() 将所有异常映射到同一个位置来拥有一个全局异常过滤器,但我建议根据您的控制器将它们分开。
  • 谢谢,我读到了这个docs.nestjs.com/exception-filters#exception-filters-1 并看到他们处理 HttpExceptions 并向客户端返回自定义响应。所以我应该创建多个过滤器来映射这些异常并返回匹配的 HttpException?
  • 在过滤器中,您可以捕获所有退出控制器的异常并将它们映射到正确的 http 代码。注解@Catch() 可以接受多个异常。但是,如果您想更具体一些,您可以为控制器的每个入口点创建过滤器。我在这里举了一个例子,如果可以帮助你,我会发现自己的异常:github.com/GabLeg/nestjs-example/blob/master/src/controllers/…
  • 嗯,是的,您也在使用if (error instanceof ...) :) 我想我可以使用全局过滤器,然后为每个自定义异常创建一个异常过滤器,对吧?就像 @Catch(KeyNotFoundException) 会返回 NestJs NotFoundException
  • 是的,您可以同时拥有全局过滤器和特定过滤器。另外,我刚刚查了一下,您可以在UseFilters() 中添加多个过滤器,这样您就可以为每个自定义异常设置一个过滤器,但我从未尝试过。是的@Catch(KeyNotFoundException) 就是这样:)

标签: typescript nestjs


【解决方案1】:

首先,我认为您当前的解决方案是完全有效的。如果您不想从服务中抛出 http 异常并在控制器中抛出 NotFound,则无法转换两者。为方便起见,您可以创建一个通用异常工厂,该工厂知道如何将您的服务异常转换为 http 异常。你也可以把它作为中间件的一部分来处理,而不用在控制器端担心它

【讨论】:

  • 嘿,谢谢你的回复。您介意多描述一下您的解决方案吗?通用工厂将充当映射器?你对中间件是什么意思,我认为这只在控制器请求进入之前运行。对于 NestJs 管道也是如此?所以你有一个转变的想法吗? :)
  • 我对您的通用工厂方法非常感兴趣,因为我仍然需要一个 Hashmap 或其他东西来映射它吗?
  • 看起来你对内置的 NestJs 解决方案有一个很好的建议......一般来说,我会创建一个 ExceptionType --&gt; HttpExceptionType 的映射,然后对于每个捕获的异常,我会检查它是否存在在键中,如果是这样,我将获得相关的 HttpExceptionType 并将捕获的异常实例化为内部异常
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-27
  • 2016-11-17
  • 2021-04-24
  • 2022-07-14
  • 2015-04-05
  • 2018-09-05
  • 1970-01-01
相关资源
最近更新 更多