problem: unhandled exception when a remote grpc gives an http error

This commit is contained in:
a10zn8
2022-12-07 21:46:05 +04:00
parent 3123e89bc8
commit bae613e8b8
3 changed files with 137 additions and 36 deletions

View File

@@ -26,14 +26,6 @@ class MockGrpcServer {
GrpcCleanupRule grpcCleanup = new GrpcCleanupRule()
ReactorBlockchainGrpc.ReactorBlockchainStub clientForServer(ReactorBlockchainGrpc.BlockchainImplBase impl) {
String serverName = InProcessServerBuilder.generateName()
grpcCleanup.register(InProcessServerBuilder
.forName(serverName).directExecutor().addService(impl).build().start());
def channel = grpcCleanup.register(InProcessChannelBuilder.forName(serverName).directExecutor().build())
return ReactorBlockchainGrpc.newReactorStub(channel)
}
ReactorBlockchainGrpc.ReactorBlockchainStub clientForServer(BlockchainGrpc.BlockchainImplBase impl){
String serverName = InProcessServerBuilder.generateName()
grpcCleanup.register(InProcessServerBuilder

View File

@@ -0,0 +1,88 @@
package io.emeraldpay.dshackle.upstream.rpcclient
import com.google.protobuf.ByteString
import io.emeraldpay.api.proto.BlockchainGrpc
import io.emeraldpay.api.proto.BlockchainOuterClass
import io.emeraldpay.api.proto.Common
import io.emeraldpay.dshackle.test.MockGrpcServer
import io.emeraldpay.dshackle.upstream.Selector
import io.emeraldpay.etherjar.rpc.RpcException
import io.emeraldpay.etherjar.rpc.RpcResponseError
import io.emeraldpay.dshackle.Chain
import io.grpc.stub.StreamObserver
import spock.lang.Specification
import java.time.Duration
import java.util.concurrent.atomic.AtomicReference
class JsonRpcGrpcClientSpec extends Specification {
def "Makes a request"() {
setup:
def mockGrpc = new MockGrpcServer()
def requested = new AtomicReference<BlockchainOuterClass.NativeCallRequest>()
def grpc = mockGrpc.clientForServer(new BlockchainGrpc.BlockchainImplBase() {
@Override
void nativeCall(BlockchainOuterClass.NativeCallRequest request, StreamObserver<BlockchainOuterClass.NativeCallReplyItem> responseObserver) {
requested.set(request)
responseObserver.onNext(BlockchainOuterClass.NativeCallReplyItem.newBuilder()
.setId(1)
.setSucceed(true)
.setPayload(ByteString.copyFromUtf8("\"hello world!\""))
.build())
responseObserver.onCompleted()
}
})
def client = new JsonRpcGrpcClient(
grpc, Chain.BITCOIN, null
).getReader()
when:
def act = client.read(
new JsonRpcRequest("test", [])
).block(Duration.ofSeconds(1))
then:
!act.hasError()
act.resultAsProcessedString == "hello world!"
requested.get() == BlockchainOuterClass.NativeCallRequest.newBuilder()
.setChain(Common.ChainRef.CHAIN_BITCOIN)
.addAllItems([
BlockchainOuterClass.NativeCallItem.newBuilder()
.setId(1)
.setMethod("test")
.setPayload(ByteString.copyFromUtf8("[]"))
.build()
])
.build()
}
def "Return error on HTTP error"() {
setup:
def mockGrpc = new MockGrpcServer()
def grpc = mockGrpc.clientForServer(new BlockchainGrpc.BlockchainImplBase() {
@Override
void nativeCall(BlockchainOuterClass.NativeCallRequest request, StreamObserver<BlockchainOuterClass.NativeCallReplyItem> responseObserver) {
responseObserver.onError(new IllegalStateException("fail"))
}
})
def client = new JsonRpcGrpcClient(
grpc, Chain.BITCOIN, null
).getReader()
when:
client.read(
new JsonRpcRequest("test", [])
).block(Duration.ofSeconds(1))
then:
def t = thrown(RpcException)
with(t.error) {
message == "Remote status code: UNKNOWN"
it.code == RpcResponseError.CODE_UPSTREAM_CONNECTION_ERROR
}
}
}