Pass an error as is (#763)
This commit is contained in:
Submodule emerald-grpc updated: f18804408f...7afb478e66
@@ -78,6 +78,18 @@ class Global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getErrorValueAsIs(errorResp: ByteArray): ByteArray? {
|
||||||
|
return runCatching {
|
||||||
|
Global.objectMapper.readTree(errorResp)
|
||||||
|
?.get("error")
|
||||||
|
?.let {
|
||||||
|
Global.objectMapper.writeValueAsBytes(it)
|
||||||
|
}
|
||||||
|
}.getOrElse {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun isSolana(chain: Chain): Boolean {
|
private fun isSolana(chain: Chain): Boolean {
|
||||||
return chain == Chain.SOLANA__MAINNET || chain == Chain.SOLANA__DEVNET || chain == Chain.SOLANA__TESTNET
|
return chain == Chain.SOLANA__MAINNET || chain == Chain.SOLANA__DEVNET || chain == Chain.SOLANA__TESTNET
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,6 +254,9 @@ open class NativeCall(
|
|||||||
error.data?.let { data ->
|
error.data?.let { data ->
|
||||||
result.setErrorData(data)
|
result.setErrorData(data)
|
||||||
}
|
}
|
||||||
|
if (error.errorAsIs != null) {
|
||||||
|
result.errorAsIs = ByteString.copyFrom(error.errorAsIs)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result.payload = ByteString.copyFrom(it.result)
|
result.payload = ByteString.copyFrom(it.result)
|
||||||
@@ -801,6 +804,7 @@ open class NativeCall(
|
|||||||
val upstreamError: ChainCallError?,
|
val upstreamError: ChainCallError?,
|
||||||
val data: String?,
|
val data: String?,
|
||||||
val upstreamSettingsData: List<Upstream.UpstreamSettingsData> = emptyList(),
|
val upstreamSettingsData: List<Upstream.UpstreamSettingsData> = emptyList(),
|
||||||
|
val errorAsIs: ByteArray? = null,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -818,7 +822,7 @@ open class NativeCall(
|
|||||||
}
|
}
|
||||||
fun from(t: Throwable): CallError {
|
fun from(t: Throwable): CallError {
|
||||||
return when (t) {
|
return when (t) {
|
||||||
is ChainException -> CallError(t.error.code, t.error.message, t.error, getDataAsSting(t.error.details), t.upstreamSettingsData)
|
is ChainException -> CallError(t.error.code, t.error.message, t.error, getDataAsSting(t.error.details), t.upstreamSettingsData, t.error.errorAsIs)
|
||||||
is RpcException -> CallError(t.code, t.rpcMessage, null, getDataAsSting(t.details))
|
is RpcException -> CallError(t.code, t.rpcMessage, null, getDataAsSting(t.details))
|
||||||
is CallFailure -> CallError(t.id, t.reason.message ?: "Upstream Error", null, null)
|
is CallFailure -> CallError(t.id, t.reason.message ?: "Upstream Error", null, null)
|
||||||
else -> {
|
else -> {
|
||||||
@@ -833,6 +837,28 @@ open class NativeCall(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is CallError) return false
|
||||||
|
|
||||||
|
if (id != other.id) return false
|
||||||
|
if (message != other.message) return false
|
||||||
|
if (upstreamError != other.upstreamError) return false
|
||||||
|
if (data != other.data) return false
|
||||||
|
if (upstreamSettingsData != other.upstreamSettingsData) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = id
|
||||||
|
result = 31 * result + message.hashCode()
|
||||||
|
result = 31 * result + (upstreamError?.hashCode() ?: 0)
|
||||||
|
result = 31 * result + (data?.hashCode() ?: 0)
|
||||||
|
result = 31 * result + upstreamSettingsData.hashCode()
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
open class CallResult @JvmOverloads constructor(
|
open class CallResult @JvmOverloads constructor(
|
||||||
|
|||||||
@@ -17,7 +17,12 @@ package io.emeraldpay.dshackle.upstream
|
|||||||
|
|
||||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
|
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
|
||||||
|
|
||||||
data class ChainCallError(val code: Int, val message: String, val details: Any?) {
|
data class ChainCallError(
|
||||||
|
val code: Int,
|
||||||
|
val message: String,
|
||||||
|
val details: Any?,
|
||||||
|
val errorAsIs: ByteArray? = null,
|
||||||
|
) {
|
||||||
|
|
||||||
constructor(code: Int, message: String) : this(code, message, null)
|
constructor(code: Int, message: String) : this(code, message, null)
|
||||||
|
|
||||||
@@ -39,4 +44,22 @@ data class ChainCallError(val code: Int, val message: String, val details: Any?)
|
|||||||
fun asException(id: ChainResponse.Id?, upstreamSettingsData: List<Upstream.UpstreamSettingsData>): ChainException {
|
fun asException(id: ChainResponse.Id?, upstreamSettingsData: List<Upstream.UpstreamSettingsData>): ChainException {
|
||||||
return ChainException(id ?: ChainResponse.NumberId(-1), this, upstreamSettingsData, false)
|
return ChainException(id ?: ChainResponse.NumberId(-1), this, upstreamSettingsData, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is ChainCallError) return false
|
||||||
|
|
||||||
|
if (code != other.code) return false
|
||||||
|
if (message != other.message) return false
|
||||||
|
if (details != other.details) return false
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int {
|
||||||
|
var result = code
|
||||||
|
result = 31 * result + message.hashCode()
|
||||||
|
result = 31 * result + (details?.hashCode() ?: 0)
|
||||||
|
return result
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,8 @@ abstract class ResponseParser<T> {
|
|||||||
state.copy(result = result)
|
state.copy(result = result)
|
||||||
}
|
}
|
||||||
} else if (field == "error") {
|
} else if (field == "error") {
|
||||||
val err = readError(parser)
|
val errorValue = Global.getErrorValueAsIs(json)
|
||||||
|
val err = readError(parser, errorValue)
|
||||||
if (err != null) {
|
if (err != null) {
|
||||||
return state.copy(error = err)
|
return state.copy(error = err)
|
||||||
}
|
}
|
||||||
@@ -154,6 +155,10 @@ abstract class ResponseParser<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun readError(parser: JsonParser): ChainCallError? {
|
fun readError(parser: JsonParser): ChainCallError? {
|
||||||
|
return readError(parser, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun readError(parser: JsonParser, errorAsIs: ByteArray?): ChainCallError? {
|
||||||
var code = 0
|
var code = 0
|
||||||
var message = ""
|
var message = ""
|
||||||
var details: Any? = null
|
var details: Any? = null
|
||||||
@@ -204,7 +209,7 @@ abstract class ResponseParser<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ChainCallError(code, message, details)
|
return ChainCallError(code, message, details, errorAsIs)
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Preparsed(
|
data class Preparsed(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package io.emeraldpay.dshackle.upstream.rpcclient.stream
|
|||||||
import com.fasterxml.jackson.core.JsonFactory
|
import com.fasterxml.jackson.core.JsonFactory
|
||||||
import com.fasterxml.jackson.core.JsonParser
|
import com.fasterxml.jackson.core.JsonParser
|
||||||
import com.fasterxml.jackson.core.JsonToken
|
import com.fasterxml.jackson.core.JsonToken
|
||||||
|
import io.emeraldpay.dshackle.Global
|
||||||
import io.emeraldpay.dshackle.upstream.ChainCallError
|
import io.emeraldpay.dshackle.upstream.ChainCallError
|
||||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
|
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcResponseError
|
||||||
import io.emeraldpay.dshackle.upstream.rpcclient.ResponseRpcParser
|
import io.emeraldpay.dshackle.upstream.rpcclient.ResponseRpcParser
|
||||||
@@ -233,7 +234,8 @@ class JsonRpcStreamParser(
|
|||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
} else if (parser.currentName == "error") {
|
} else if (parser.currentName == "error") {
|
||||||
return SingleResponse(response?.result, responseRpcParser.readError(parser))
|
val errorValue = Global.getErrorValueAsIs(firstBytes)
|
||||||
|
return SingleResponse(response?.result, responseRpcParser.readError(parser, errorValue))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package io.emeraldpay.dshackle.upstream.rpcclient
|
|||||||
|
|
||||||
import io.emeraldpay.dshackle.upstream.ChainCallError
|
import io.emeraldpay.dshackle.upstream.ChainCallError
|
||||||
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
|
import io.emeraldpay.dshackle.upstream.ethereum.rpc.RpcException
|
||||||
import nl.jqno.equalsverifier.EqualsVerifier
|
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
|
|
||||||
class JsonRpcErrorSpec extends Specification {
|
class JsonRpcErrorSpec extends Specification {
|
||||||
@@ -24,11 +23,4 @@ class JsonRpcErrorSpec extends Specification {
|
|||||||
act.message == "test test"
|
act.message == "test test"
|
||||||
act.details == "foo bar"
|
act.details == "foo bar"
|
||||||
}
|
}
|
||||||
|
|
||||||
def "Equals"() {
|
|
||||||
when:
|
|
||||||
def v = EqualsVerifier.forClass(ChainCallError)
|
|
||||||
then:
|
|
||||||
v.verify()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user