problem: unnecessary exceptions in logs when an unavailable blockchain is requested

This commit is contained in:
Igor Artamonov
2019-12-30 22:22:30 -05:00
parent 38bb9a0fa5
commit d69ee41e7a
4 changed files with 38 additions and 11 deletions

View File

@@ -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)
}
}

View File

@@ -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<CallContext<RawCallDetails>> {
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)
}

View File

@@ -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<SimpleAddress> {
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<Wei> {
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)

View File

@@ -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<Notification>()
val details = TxDetails(
@@ -208,7 +209,7 @@ class TrackTx(
private fun loadWeight(tx: TxDetails): Mono<TxDetails> {
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<TxDetails> {
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