侦听器未捕获nestjs中guard抛出的错误
我有一个在应用程序中注册的全局防护,它位于全局模块侦听器未捕获nestjs中guard抛出的错误,nestjs,Nestjs,我有一个在应用程序中注册的全局防护,它位于全局模块common.module.ts const HeaderGuardGlobal = { provide: APP_GUARD, useClass: HeaderGuard }; @Global() @Module({ imports: [ LoggerModule ], providers: [ HeaderGuardGlobal ], exports: [] }) header.guard.ts:
common.module.ts
const HeaderGuardGlobal = {
provide: APP_GUARD,
useClass: HeaderGuard
};
@Global()
@Module({
imports: [ LoggerModule ],
providers: [ HeaderGuardGlobal ],
exports: []
})
header.guard.ts:
async canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const userName = request.headers[HEADERS.USER_NAME];
if(!userName) {
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
user.controller.ts:
@Controller('user')
@UseInterceptors(setAuthenticateHeaderInterceptor)
export class ClientController {
我试图实现的是,当header.guard.ts
抛出禁止的
异常时,authenticate header.interceptor.ts
将捕获异常并将其传播到全局http筛选器,但在此之前,我想向响应对象添加一个头
我面临的问题是,当警卫抛出异常时,拦截器无法捕获它。但是,当从路由处理程序或服务抛出相同的错误时,拦截器能够捕获它
为了理解执行上下文,我仔细阅读了,并在第节中找到了下面的语句
管道、控制器或服务引发的任何错误都可以在拦截器的catchError操作符中读取
这份声明并没有提到任何关于后卫的事情,所以我认为我试图实现的目标是不可能的
我无法理解为什么在防护中抛出的错误没有被拦截器捕获。如果有人觉得需要更多的信息,上面的代码片段只包括我认为这个问题需要的部分。然后我会提供它。文档正确地说明了,正如您所提到的 管道、控制器或服务引发的任何错误都可以在拦截器的catchError操作符中读取
如下文所述,在拦截器关闭之前执行防护,因此,拦截器的
catchError
方法无法捕获拦截器的错误。您最好的选择是制作一个扩展您的GlobalFilter
的过滤器,在那里添加您的逻辑,然后调用super.catch(exception)
调用其余的逻辑。感谢您的回复。但我仍然不明白为什么拦截器无法捕获错误。拦截器及其上下文是在警卫已经运行其canActivate
方法之后创建的。在把这些文档放在一起之前,我花了很多时间试图弄清楚何时从何处调用方法。这就是请求生命周期的工作方式。在拦截器中,Nest注入一个切入点
,以允许从拦截器移动到控制器,然后管理请求后逻辑,但所有这些都发生在中间件和保护已经执行之后。简而言之,这是框架的一个限制,但是TL;DR:这是一个允许根据特定情况插入其他代码的函数。在这种情况下,情况是此时此地激活了哪个类和哪个方法(即哪个控制器和哪个路由处理程序)。
@Controller('user')
@UseInterceptors(setAuthenticateHeaderInterceptor)
export class ClientController {