problem: unnecessary exceptions in logs when an unavailable blockchain is requested
This commit is contained in:
17
src/main/kotlin/io/emeraldpay/dshackle/SilentException.kt
Normal file
17
src/main/kotlin/io/emeraldpay/dshackle/SilentException.kt
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user