这是我最近一直在处理的一个很好的问题。
对于某些项目,我们希望在应用程序的不同域之间共享业务错误。我们最终得到的是简单地拥有一个共享(或公用)文件夹或模块,以暴露我们在应用程序中遇到的不同域特定错误。
除此之外,我们还使用了 Nest 的常见异常,这些异常非常适合这项工作!
最后,我们使用共享域特定的业务错误自定义常见的 Nest 异常。
极简user.service.ts复现例子:
import { NotFoundException, Logger } from '@nestjs/common';
import { UserBusinessErrors } from '../../shared/errors/user/user.business-errors';
// some code ...
// Find the users from the usersIds array
const dbUsers = await this.userRepository.find({ id: In(usersIds) });
// If none was found, raise an error
if (!dbUsers) {
Logger.error(`Could not find user with IDs: ${usersIds}`, '', 'UserService', true);
throw new NotFoundException(UserBusinessErrors.NotFound);
}
与其对应的user.business-errors.ts 文件位于共享或公共模块/文件夹中(例如src/shared/errors/user/user.business-errors.ts):
export const UserBusinessErrors = {
// ... other errors
NotFound: {
apiErrorCode: 'E_0002_0002',
errorMessage: 'User not found',
reason: `Provided user ids doesn't exist in DB`
},
// ... other errors
}
或者有时如果你想要更通用的东西,你也可以使用共享错误:
import { InternalServerErrorException, Logger } from '@nestjs/common';
import { SharedBusinessErrors } from '../../shared/errors/shared.business-errors';
// some code ...
try {
// ...
} catch (error) {
Logger.log(SharedBusinessErrors.DbSaveError, 'UserService');
throw new InternalServerErrorException(SharedBusinessErrors.DbSaveError, error.stack);
}
对应的shared.business-errors.ts文件:
export const SharedBusinessErrors = {
DbSaveError: {
apiErrorCode: 'E_0001_0001',
errorMessage: `Error when trying to save resource into the DB`,
reason: 'Internal server error'
},
// ... other errors
}
最后想对您的不同问题发表评论:
创建全局或模块级过滤器是否可行?用 UseFilters 装饰每个端点似乎很麻烦。
我们也可以利用Nest filters customization 并在控制器或路由级别使用装饰器。但对我来说,您实际上仍然需要指定它与哪些业务错误相关,以便为您的业务错误增加价值并且无论如何您都需要在服务中引发错误。因此,只有一些包含域特定(或业务)错误的共享文件和更通用的错误在 imo 中很好(但可能不是最干净/最优雅的解决方案)。
您可以将业务错误文件放在每个模块的文件夹中,并添加一个 webpack 配置以将所有这些文件收集并连接到一个唯一的文件中。
最后,如果您需要跨多个项目的特定领域或共享错误,我猜您甚至可以创建一个 npm 包。
如果我有任何不清楚的地方或/以及它是否能让您更深入地了解,请告诉我!