【发布时间】: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)会返回 NestJsNotFoundException -
是的,您可以同时拥有全局过滤器和特定过滤器。另外,我刚刚查了一下,您可以在
UseFilters()中添加多个过滤器,这样您就可以为每个自定义异常设置一个过滤器,但我从未尝试过。是的@Catch(KeyNotFoundException)就是这样:)
标签: typescript nestjs