我有一个全局防护,该全局防护已在应用程序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);
}
我有一个控制范围的拦截器authenticate-header.interceptor.ts
@Injectable()
export class setAuthenticateHeaderInterceptor<T> implements NestInterceptor<T, Response<T>> {
public constructor() {}
intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
const req = context.switchToHttp().getRequest();
const res = context.switchToHttp().getResponse();
return next
.handle()
.pipe(
catchError(err => {
console.log('ERROR: ', err);
res.setHeader('sampleKey', 'sampleValue');
return throwError(err);
})
)
}
}
user.controller.ts:
@Controller('user')
@UseInterceptors(setAuthenticateHeaderInterceptor)
export class ClientController {
我要实现的是,当header.guard.ts
抛出Forbidden
异常时,authenticate-header.interceptor.ts
会捕获该异常并将其传播到全局http过滤器,但是在执行之前我想在响应对象中添加标题。
我面临的问题是当守卫抛出异常时,拦截器无法捕获它。但是,当从路由处理程序或服务中抛出相同的错误时,拦截器便可以捕获该错误。
我通过request-lifecycle来了解执行上下文,并在interceptors部分找到了以下语句。
管道,控制器或服务抛出的任何错误都可以在拦截器的catchError运算符中读取。
该声明未提及任何有关警卫的信息,因此我假设我试图实现的目标是不可能的。
我无法弄清楚为什么拦截器没有捕获到在警卫内部抛出的错误。如果有人觉得需要更多信息,以上代码片段仅包含我认为对该问题必要的部分。然后我将提供它。
答案 0 :(得分:0)
您所提到的文档正确陈述了
如以下summary部分所述,管道,控制器或服务抛出的任何错误都可以在拦截器的catchError运算符中读取。
防护程序在拦截器执行之前执行,因此,它们的错误无法在拦截器的# test_b.py
import non_test
import configs
import importlib
importlib.reload(non_test)
importlib.reload(configs)
def test_class():
SomeClass()
方法中捕获。最好的选择是制作一个扩展catchError
的过滤器,在其中添加逻辑,然后调用GlobalFilter
来调用其余的逻辑。