【发布时间】:2020-07-20 02:27:45
【问题描述】:
我有一个全局守卫,它在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 运算符中读取。
声明中没有提到任何关于守卫的内容,所以我假设我想要实现的目标是不可能的。
我无法弄清楚为什么拦截器没有捕获到守卫内抛出的错误。如果有人觉得需要更多信息,上面的代码 sn-ps 仅包含我认为对问题必要的部分。那我来提供。
【问题讨论】:
标签: nestjs