From d69ee41e7acd3e5a7fc6f7e4b17c13efea9b9bfe Mon Sep 17 00:00:00 2001 From: Igor Artamonov Date: Mon, 30 Dec 2019 22:22:30 -0500 Subject: [PATCH] problem: unnecessary exceptions in logs when an unavailable blockchain is requested --- .../io/emeraldpay/dshackle/SilentException.kt | 17 ++++++++++++++++ .../io/emeraldpay/dshackle/rpc/NativeCall.kt | 5 +++-- .../emeraldpay/dshackle/rpc/TrackAddress.kt | 20 +++++++++++++------ .../io/emeraldpay/dshackle/rpc/TrackTx.kt | 7 ++++--- 4 files changed, 38 insertions(+), 11 deletions(-) create mode 100644 src/main/kotlin/io/emeraldpay/dshackle/SilentException.kt diff --git a/src/main/kotlin/io/emeraldpay/dshackle/SilentException.kt b/src/main/kotlin/io/emeraldpay/dshackle/SilentException.kt new file mode 100644 index 00000000..453fe651 --- /dev/null +++ b/src/main/kotlin/io/emeraldpay/dshackle/SilentException.kt @@ -0,0 +1,17 @@ +package io.emeraldpay.dshackle + +import io.emeraldpay.grpc.Chain + +/** + * Exception that should be handled/logged without a stacktrace in production + */ +open class SilentException(message: String) : Exception(message) { + + + /** + * Blockchain is not available or not supported by current instance of the Dshackle + */ + class UnsupportedBlockchain(val blockchainId: Int): SilentException("Unsupported blockchain $blockchainId") { + constructor(chain: Chain) : this(chain.id) + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt index 9c597f0f..8d40a79c 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/NativeCall.kt @@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.rpc import com.fasterxml.jackson.databind.ObjectMapper import com.google.protobuf.ByteString import io.emeraldpay.api.proto.BlockchainOuterClass +import io.emeraldpay.dshackle.SilentException import io.emeraldpay.dshackle.upstream.* import io.emeraldpay.dshackle.quorum.AlwaysQuorum import io.emeraldpay.dshackle.quorum.CallQuorum @@ -81,10 +82,10 @@ class NativeCall( fun prepareCall(request: BlockchainOuterClass.NativeCallRequest): Flux> { val chain = Chain.byId(request.chain.number) if (chain == Chain.UNSPECIFIED) { - return Flux.error(CallFailure(0, Exception("Invalid chain id: ${request.chain.number}"))) + return Flux.error(CallFailure(0, SilentException.UnsupportedBlockchain(request.chain.number))) } val upstream = upstreams.getUpstream(chain) - ?: return Flux.error(CallFailure(0, Exception("Chain ${chain.id} is unavailable"))) + ?: return Flux.error(CallFailure(0, SilentException.UnsupportedBlockchain(chain))) return prepareCall(request, upstream) } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackAddress.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackAddress.kt index ef092d71..c23192d1 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackAddress.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackAddress.kt @@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.rpc import io.emeraldpay.api.proto.BlockchainOuterClass import io.emeraldpay.api.proto.Common import io.emeraldpay.dshackle.Defaults +import io.emeraldpay.dshackle.SilentException import io.emeraldpay.dshackle.upstream.Selector import io.emeraldpay.dshackle.upstream.Upstreams import io.emeraldpay.grpc.Chain @@ -34,7 +35,6 @@ import reactor.core.publisher.Mono import reactor.core.publisher.TopicProcessor import reactor.core.publisher.toFlux import reactor.core.scheduler.Scheduler -import java.lang.Exception import java.time.Duration import java.time.Instant import java.util.* @@ -95,10 +95,10 @@ class TrackAddress( private fun initializeSimple(request: BlockchainOuterClass.BalanceRequest): Flux { val chain = Chain.byId(request.asset.chainValue) if (!upstreams.isAvailable(chain)) { - return Flux.error(Exception("Unsupported chain ${request.asset.chainValue}")) + return Flux.error(SilentException.UnsupportedBlockchain(request.asset.chainValue)) } if (request.asset.code?.toLowerCase() != "ether") { - return Flux.error(Exception("Unsupported asset ${request.asset.code}")) + return Flux.error(SilentException("Unsupported asset ${request.asset.code}")) } return when { request.address.addrTypeCase == Common.AnyAddress.AddrTypeCase.ADDRESS_SINGLE -> @@ -133,8 +133,16 @@ class TrackAddress( buildResponse(it) } Flux.merge(current, bus).doFinally { stopTracking(tracked) } - }.doOnError { t -> - log.warn("Failed to process subscription", t) + } + .doOnError { t -> + if (t is SilentException) { + if (t is SilentException.UnsupportedBlockchain) { + log.warn("Unsupported blockchain: ${t.blockchainId}") + } + log.debug("Failed to process subscription", t) + } else { + log.warn("Failed to process subscription", t) + } } } } @@ -167,7 +175,7 @@ class TrackAddress( } fun getBalance(addr: SimpleAddress): Mono { - val up = upstreams.getUpstream(addr.chain) ?: return Mono.error(Exception("Unsupported chain: ${addr.chain}")) + val up = upstreams.getUpstream(addr.chain) ?: return Mono.error(SilentException.UnsupportedBlockchain(addr.chain)) return up.getApi(Selector.empty) .flatMap { api -> api.executeAndConvert(Commands.eth().getBalance(addr.address, BlockTag.LATEST)) } .timeout(Defaults.timeout) diff --git a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackTx.kt b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackTx.kt index 3daacb69..fda779c6 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackTx.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/rpc/TrackTx.kt @@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.rpc import com.google.protobuf.ByteString import io.emeraldpay.api.proto.BlockchainOuterClass import io.emeraldpay.api.proto.Common +import io.emeraldpay.dshackle.SilentException import io.emeraldpay.dshackle.upstream.Selector import io.emeraldpay.dshackle.upstream.Upstream import io.emeraldpay.dshackle.upstream.Upstreams @@ -142,7 +143,7 @@ class TrackTx( fun prepareTracking(request: BlockchainOuterClass.TxStatusRequest): TxDetails { val chain = Chain.byId(request.chainValue) if (!clients.containsKey(chain)) { - throw Exception("Unsupported blockchain: ${chain}") + throw SilentException.UnsupportedBlockchain(chain) } val bus = TopicProcessor.create() val details = TxDetails( @@ -208,7 +209,7 @@ class TrackTx( private fun loadWeight(tx: TxDetails): Mono { val upstream = upstreams.getUpstream(tx.chain) - ?: return Mono.error(Exception("Unsupported blockchain: ${tx.chain}")) + ?: return Mono.error(SilentException.UnsupportedBlockchain(tx.chain)) return upstream.getApi(Selector.empty) .flatMap { api -> api.executeAndConvert(Commands.eth().getBlock(tx.status.blockHash)) } .map { block -> @@ -249,7 +250,7 @@ class TrackTx( private fun checkForUpdate(tx: TxDetails): Mono { val initialStatus = tx.status - val upstream = upstreams.getUpstream(tx.chain) ?: return Mono.error(Exception("Unsupported blockchain: ${tx.chain}")) + val upstream = upstreams.getUpstream(tx.chain) ?: return Mono.error(SilentException.UnsupportedBlockchain(tx.chain)) val execution = upstream.getApi(Selector.empty) .flatMap { api -> api.executeAndConvert(Commands.eth().getTransaction(tx.txid)) } return execution