我有一个通过GRPC连接到网关的HTTP服务器。网关还连接到其他网关。 GRPC微服务。流程如下所示:
客户端-> HttpServer-> GRPC服务器(网关)-> GRPC微服务服务器X
我目前处理错误的方式是这样的(请告诉我是否有更好的做法),为了简洁起见,我只会显示nessaccery代码
GRPC微服务服务器X
@GrpcMethod() get(clientDetails: Records.UserDetails.AsObject): Records.RecordResponse.AsObject {
this.logger.log("Get Record for client");
throw new RpcException({message: 'some error', code: status.DATA_LOSS})
}
这个简单的方法会向GRPC客户端抛出一个错误(可以正常工作)
GRPC服务器
@GrpcMethod() async get(data: Records.UserDetails.AsObject, metaData): Promise<Records.RecordResponse.AsObject> {
try {
return await this.hpGrpcRecordsService.get(data).toPromise();
} catch(e) {
throw new RpcException(e)
}
}
Grpc服务器捕获到错误,而该错误又被捕获,请购买全局异常处理程序(这很好)
@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
if( Object.prototype.hasOwnProperty.call(exception, 'message') &&
Object.prototype.hasOwnProperty.call(exception.message, 'code') &&
exception.message.code === 2
){
exception.message.code = 13
}
return throwError(exception.getError());
}
}
这会将错误返回给Http服务器(grpc客户端,可以正常工作)
现在,当它到达Http服务器时,我希望我可以设置另一个RPC异常处理程序,并将错误转换为HTTP除外。但我不确定是否可行,我只使用过Nest几天,但尚未完全了解它。
这里是我希望做的一个例子(代码不起作用,只是我想要的例子)。 id更喜欢全局捕获异常,而不是到处都有try / catch块
@Catch(RpcException)
export class ExceptionFilter implements RpcExceptionFilter<RpcException> {
catch(exception: RpcException, host: ArgumentsHost): Observable<any> {
//Map UNKNOWN(2) grpc error to INTERNAL(13)
if( Object.prototype.hasOwnProperty.call(exception, 'message') &&
Object.prototype.hasOwnProperty.call(exception.message, 'code') &&
exception.message.code === 2
){ exception.message.code = 13 }
throw new HttpException('GOT EM', HttpStatus.BAD_GATEWAY)
}
}
答案 0 :(得分:2)
我已经被困在同一个地方一段时间了。看来可行的是,只有您作为消息发送的字符串才在HTTP服务器上收到。 因此,下面的代码可以用作HTTP服务器中的过滤器,但是您必须通过消息字符串检查状态。
@Catch(RpcException)
export class HttpExceptionFilter implements ExceptionFilter {
catch(exception: RpcException, host: ArgumentsHost) {
const err = exception.getError();
// console.log(err);
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const request = ctx.getRequest<Request>();
response
.json({
message: err["details"],
code: err['code'],
timestamp: new Date().toISOString(),
path: request.url,
});
}
}
if(err['details'] === UserBusinessErrors.InvalidCredentials.message){
this.logger.error(e);
throw new HttpException( UserBusinessErrors.InvalidCredentials.message, 409)
} else {
this.logger.error(e);
throw new InternalServerErrorException();
}