[CORDA-1264]: Ensure correct serialisation and masking for throwables raised by a node and propagated through RPC. (#2902)

This commit is contained in:
Michele Sollecito
2018-03-29 14:40:40 +01:00
committed by GitHub
parent db29fceb4c
commit 33af80ac55
19 changed files with 432 additions and 18 deletions

View File

@ -0,0 +1,32 @@
package net.corda.nodeapi.exceptions
import net.corda.core.CordaRuntimeException
import java.io.InvalidClassException
// could change to use package name matching but trying to avoid reflection for now
private val whitelisted = setOf(
InvalidClassException::class,
RpcSerializableError::class
)
/**
* An [Exception] to signal RPC clients that something went wrong within a Corda node.
*/
class InternalNodeException(message: String) : CordaRuntimeException(message) {
companion object {
private const val DEFAULT_MESSAGE = "Something went wrong within the Corda node."
fun defaultMessage(): String = DEFAULT_MESSAGE
fun obfuscateIfInternal(wrapped: Throwable): Throwable {
(wrapped as? CordaRuntimeException)?.setCause(null)
return when {
whitelisted.any { it.isInstance(wrapped) } -> wrapped
else -> InternalNodeException(DEFAULT_MESSAGE)
}
}
}
}

View File

@ -0,0 +1,11 @@
package net.corda.nodeapi.exceptions
import net.corda.core.CordaRuntimeException
import net.corda.core.crypto.SecureHash
class OutdatedNetworkParameterHashException(old: SecureHash, new: SecureHash) : CordaRuntimeException(TEMPLATE.format(old, new)), RpcSerializableError {
private companion object {
private const val TEMPLATE = "Refused to accept parameters with hash %s because network map advertises update with hash %s. Please check newest version"
}
}

View File

@ -5,4 +5,4 @@ import net.corda.core.CordaRuntimeException
/**
* Thrown to indicate that the command was rejected by the node, typically due to a special temporary mode.
*/
class RejectedCommandException(msg: String) : CordaRuntimeException(msg)
class RejectedCommandException(message: String) : CordaRuntimeException(message), RpcSerializableError

View File

@ -0,0 +1,9 @@
package net.corda.nodeapi.exceptions
import net.corda.core.serialization.CordaSerializable
/**
* Allows an implementing [Throwable] to be propagated to RPC clients.
*/
@CordaSerializable
interface RpcSerializableError

View File

@ -0,0 +1,15 @@
package net.corda.nodeapi.exceptions.adapters
import net.corda.core.internal.concurrent.mapError
import net.corda.core.messaging.FlowHandle
import net.corda.core.serialization.CordaSerializable
import net.corda.nodeapi.exceptions.InternalNodeException
/**
* Adapter able to mask errors within a Corda node for RPC clients.
*/
@CordaSerializable
data class InternalObfuscatingFlowHandle<RESULT>(val wrapped: FlowHandle<RESULT>) : FlowHandle<RESULT> by wrapped {
override val returnValue = wrapped.returnValue.mapError(InternalNodeException.Companion::obfuscateIfInternal)
}

View File

@ -0,0 +1,22 @@
package net.corda.nodeapi.exceptions.adapters
import net.corda.core.internal.concurrent.mapError
import net.corda.core.mapErrors
import net.corda.core.messaging.FlowProgressHandle
import net.corda.core.serialization.CordaSerializable
import net.corda.nodeapi.exceptions.InternalNodeException
/**
* Adapter able to mask errors within a Corda node for RPC clients.
*/
@CordaSerializable
class InternalObfuscatingFlowProgressHandle<RESULT>(val wrapped: FlowProgressHandle<RESULT>) : FlowProgressHandle<RESULT> by wrapped {
override val returnValue = wrapped.returnValue.mapError(InternalNodeException.Companion::obfuscateIfInternal)
override val progress = wrapped.progress.mapErrors(InternalNodeException.Companion::obfuscateIfInternal)
override val stepsTreeIndexFeed = wrapped.stepsTreeIndexFeed?.mapErrors(InternalNodeException.Companion::obfuscateIfInternal)
override val stepsTreeFeed = wrapped.stepsTreeFeed?.mapErrors(InternalNodeException.Companion::obfuscateIfInternal)
}