problem: looses upstream error details
This commit is contained in:
@@ -284,11 +284,7 @@ open class NativeCall(
|
||||
Mono.just(ctx).flatMap(this::executeOnRemote)
|
||||
)
|
||||
.onErrorResume {
|
||||
if (it is CallFailure) {
|
||||
Mono.just(CallResult.fail(it.id, ctx.nonce, it.reason))
|
||||
} else {
|
||||
Mono.just(CallResult.fail(ctx.id, ctx.nonce, it))
|
||||
}
|
||||
Mono.just(CallResult.fail(ctx.id, ctx.nonce, it))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,21 +306,14 @@ open class NativeCall(
|
||||
CallResult(ctx.id, ctx.nonce, bytes, null, it.signature, ctx.upstream.getId())
|
||||
}
|
||||
.onErrorResume { t ->
|
||||
val failure = when (t) {
|
||||
is CallFailure -> CallResult.fail(t.id, ctx.nonce, t.reason)
|
||||
is JsonRpcException -> CallResult.fail(ctx.id, ctx.nonce, t.error.code, t.error.message)
|
||||
else -> CallResult.fail(ctx.id, ctx.nonce, t)
|
||||
}
|
||||
Mono.just(failure)
|
||||
Mono.just(CallResult.fail(ctx.id, ctx.nonce, t))
|
||||
}
|
||||
.switchIfEmpty(
|
||||
Mono.fromSupplier {
|
||||
counter.get().let { attempts ->
|
||||
CallResult.fail(
|
||||
ctx.id,
|
||||
ctx.nonce,
|
||||
1,
|
||||
errorMessage(attempts, ctx.payload.method)
|
||||
ctx.id, ctx.nonce,
|
||||
CallError(1, "No response or no available upstream for ${ctx.payload.method}", null)
|
||||
).also {
|
||||
countFailure(attempts, ctx)
|
||||
}
|
||||
@@ -484,7 +473,15 @@ open class NativeCall(
|
||||
is JsonRpcException -> CallError(t.id.asNumber().toInt(), t.error.message, t.error)
|
||||
is RpcException -> CallError(t.code, t.rpcMessage, null)
|
||||
is CallFailure -> CallError(t.id, t.reason.message ?: "Upstream Error", null)
|
||||
else -> CallError(1, t.message ?: "Upstream Error", null)
|
||||
else -> {
|
||||
// May only happen if it's an unhandled exception.
|
||||
// In this case try to find a meaningless details in the stack. Most important reason for doing that is to find an ID of the request
|
||||
if (t.cause != null) {
|
||||
from(t.cause!!)
|
||||
} else {
|
||||
CallError(1, t.message ?: "Upstream Error", null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -503,8 +500,8 @@ open class NativeCall(
|
||||
return CallResult(id, nonce, result, null, signature, upstreamId)
|
||||
}
|
||||
|
||||
fun fail(id: Int, nonce: Long?, errorCore: Int, errorMessage: String): CallResult {
|
||||
return CallResult(id, nonce, null, CallError(errorCore, errorMessage, null), null, null)
|
||||
fun fail(id: Int, nonce: Long?, error: CallError): CallResult {
|
||||
return CallResult(id, nonce, null, error, null, null)
|
||||
}
|
||||
|
||||
fun fail(id: Int, nonce: Long?, error: Throwable): CallResult {
|
||||
|
||||
@@ -34,6 +34,8 @@ import io.emeraldpay.dshackle.upstream.Selector
|
||||
import io.emeraldpay.dshackle.upstream.MultistreamHolder
|
||||
import io.emeraldpay.dshackle.upstream.calls.DefaultEthereumMethods
|
||||
import io.emeraldpay.dshackle.upstream.calls.ManagedCallMethods
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcError
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcException
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.signature.ResponseSigner
|
||||
@@ -156,6 +158,35 @@ class NativeCallSpec extends Specification {
|
||||
.verify(Duration.ofSeconds(1))
|
||||
}
|
||||
|
||||
def "Returns error details from remote"() {
|
||||
setup:
|
||||
def quorum = new AlwaysQuorum()
|
||||
|
||||
def nativeCall = nativeCall()
|
||||
nativeCall.quorumReaderFactory = Mock(QuorumReaderFactory) {
|
||||
1 * create(_, _, _) >> Mock(Reader) {
|
||||
1 * read(new JsonRpcRequest("eth_test", [], 10)) >> Mono.error(
|
||||
new JsonRpcException(JsonRpcResponse.Id.from(12), new JsonRpcError(-32123, "Foo Bar", "Foo Bar Baz"))
|
||||
)
|
||||
}
|
||||
}
|
||||
def call = new NativeCall.ValidCallContext(12, 10, TestingCommons.multistream(TestingCommons.api()), Selector.empty, quorum,
|
||||
new NativeCall.ParsedCallDetails("eth_test", []))
|
||||
|
||||
when:
|
||||
def resp = nativeCall.executeOnRemote(call).block(Duration.ofSeconds(1))
|
||||
then:
|
||||
resp.isError()
|
||||
with(resp.getError()) {
|
||||
message == "Foo Bar"
|
||||
upstreamError != null
|
||||
with (upstreamError) {
|
||||
code == -32123
|
||||
details == "Foo Bar Baz"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def "Packs call exception into response with id"() {
|
||||
setup:
|
||||
def nativeCall = nativeCall()
|
||||
|
||||
Reference in New Issue
Block a user