I've been at this all day and can't seem to find a solution,
please help :)
The service communication works, the issue is with the error handling...
Service-A is invoked via HTTP. (probably not relevant but just in case)
Service-A calls Service-B via RPC.
Service-B throws an error.
an exception filter on Service-B's controller catches that error and translates it to a RpcException
and returns that to to Service-A.
Service-A receives an Error
not a RpcExcpetion
.
The error is caught in the global error handler as it is not recognized as a RpcException
(would have been caught in Service-B's RpcExceptionFilter
...)
@Module({
imports: [...],
controllers: [...],
providers: [{
provide: 'somePackage',
useFactory(configService: ConfigService) {
return ClientProxyFactory.create(
{
transport: Transport.GRPC,
options: {
url: 'localhost:5000',
package: 'somePackage',
protoPath: 'pathToProto',
},
}
);
},
inject: [ConfigService],
}]
})
export class ServiceA implements OnModuleInit {
private someService: SomeServiceClient;
onModuleInit(): any {
this.someService = this.client.getService<SomeServiceClient>('SomeService');
}
constructor(@Inject(somePackage) private client: ClientGrpc)
}
await lastValueFrom(this.someService.workWork(workWorkRequest));
catch(exception: RpcException){
const rpcException: RpcException = someConversionFunction(exception);
return throwError(() => rpcException.getError());
}
this is what thrown on service-a:
[error][2022-05-30T18:58:13.132Z]-[App/Main] - 9 FAILED_PRECONDITION: Some Service-B error message
if i try catch the call and log the error:
Error: 9 FAILED_PRECONDITION: Some Service-B error message
at Object.callErrorFromStatus (@grpc/grpc-js/src/call.ts:81:24)
at Object.onReceiveStatus (@grpc/grpc-js/src/client.ts:343:36)
at Object.onReceiveStatus (@grpc/grpc-js/src/client-interceptors.ts:462:34)
at Object.onReceiveStatus (@grpc/grpc-js/src/client-interceptors.ts:424:48)
at @grpc/grpc-js/src/call-stream.ts:323:24
at processTicksAndRejections (node:internal/process/task_queues:78:11) {
code: 9,
details: 'Some Service-B error message',
metadata: Metadata { internalRepr: Map(0) {}, options: {} }
}
what i expect is basically the same, just as a RpcError:
RpcException [Error]: Some Service-B error message
I've tried to minimize the code as much as possible...
Any input is welcome...
Thanks!
If anyone stumbles across this,
It is now possible to add an error serializer when creating the ClientProxy like so:
class ErrorHandlingProxy extends ClientGrpcProxy {
serializeError(err) {
return new RpcException(err);
}
}
@Module({
providers: [
{
provide: 'HERO_PACKAGE',
useFactory() {
return new ErrorHandlingProxy(grpcClientOptions.options);
},
},
],
controllers: [HeroController],
})
export class HeroModule {}
More details in this issue