侦听器未捕获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 {