mirror of
https://github.com/corda/corda.git
synced 2024-12-21 13:57:54 +00:00
NOTICK Do not replace stacktrace for local errors (#6635)
We should not overwrite the stack trace of local errors thrown by `FlowContinuation.Throw` as it hides the real cause of the error. Exceptions received from peer nodes are still overwritten.
This commit is contained in:
parent
abfe83626f
commit
742312b85a
@ -237,12 +237,11 @@ class FlowStateMachineImpl<R>(override val id: StateMachineRunId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun Throwable.fillInLocalStackTrace(): Throwable {
|
private fun Throwable.fillInLocalStackTrace(): Throwable {
|
||||||
fillInStackTrace()
|
// Fill in the stacktrace when the exception originates from another node
|
||||||
// provide useful information that can be displayed to the user
|
|
||||||
// reflection use to access private field
|
|
||||||
when (this) {
|
when (this) {
|
||||||
is UnexpectedFlowEndException -> {
|
is UnexpectedFlowEndException -> {
|
||||||
DeclaredField<Party?>(UnexpectedFlowEndException::class.java, "peer", this).value?.let {
|
DeclaredField<Party?>(UnexpectedFlowEndException::class.java, "peer", this).value?.let {
|
||||||
|
fillInStackTrace()
|
||||||
stackTrace = arrayOf(
|
stackTrace = arrayOf(
|
||||||
StackTraceElement(
|
StackTraceElement(
|
||||||
"Received unexpected counter-flow exception from peer ${it.name}",
|
"Received unexpected counter-flow exception from peer ${it.name}",
|
||||||
@ -255,6 +254,7 @@ class FlowStateMachineImpl<R>(override val id: StateMachineRunId,
|
|||||||
}
|
}
|
||||||
is FlowException -> {
|
is FlowException -> {
|
||||||
DeclaredField<Party?>(FlowException::class.java, "peer", this).value?.let {
|
DeclaredField<Party?>(FlowException::class.java, "peer", this).value?.let {
|
||||||
|
fillInStackTrace()
|
||||||
stackTrace = arrayOf(
|
stackTrace = arrayOf(
|
||||||
StackTraceElement(
|
StackTraceElement(
|
||||||
"Received counter-flow exception from peer ${it.name}",
|
"Received counter-flow exception from peer ${it.name}",
|
||||||
|
@ -389,22 +389,20 @@ class StartedFlowTransition(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun convertErrorMessageToException(errorMessage: ErrorSessionMessage, peer: Party): Throwable {
|
private fun convertErrorMessageToException(errorMessage: ErrorSessionMessage, peer: Party): Throwable {
|
||||||
val exception: Throwable = if (errorMessage.flowException == null) {
|
return if (errorMessage.flowException == null) {
|
||||||
UnexpectedFlowEndException("Counter-flow errored", cause = null, originalErrorId = errorMessage.errorId)
|
UnexpectedFlowEndException("Counter-flow errored", cause = null, originalErrorId = errorMessage.errorId).apply {
|
||||||
} else {
|
DeclaredField<Party?>(
|
||||||
errorMessage.flowException.originalErrorId = errorMessage.errorId
|
|
||||||
errorMessage.flowException
|
|
||||||
}
|
|
||||||
when (exception) {
|
|
||||||
// reflection used to access private field
|
|
||||||
is UnexpectedFlowEndException -> DeclaredField<Party?>(
|
|
||||||
UnexpectedFlowEndException::class.java,
|
UnexpectedFlowEndException::class.java,
|
||||||
"peer",
|
"peer",
|
||||||
exception
|
this
|
||||||
).value = peer
|
).value = peer
|
||||||
is FlowException -> DeclaredField<Party?>(FlowException::class.java, "peer", exception).value = peer
|
|
||||||
}
|
}
|
||||||
return exception
|
} else {
|
||||||
|
errorMessage.flowException.apply {
|
||||||
|
originalErrorId = errorMessage.errorId
|
||||||
|
DeclaredField<Party?>(FlowException::class.java, "peer", errorMessage.flowException).value = peer
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectUncloseableSessions(sessionIds: Collection<SessionId>, checkpoint: Checkpoint): List<Throwable> {
|
private fun collectUncloseableSessions(sessionIds: Collection<SessionId>, checkpoint: Checkpoint): List<Throwable> {
|
||||||
|
@ -307,7 +307,7 @@ class FlowFrameworkTests {
|
|||||||
.isThrownBy { receivingFiber.resultFuture.getOrThrow() }
|
.isThrownBy { receivingFiber.resultFuture.getOrThrow() }
|
||||||
.withMessage("Nothing useful")
|
.withMessage("Nothing useful")
|
||||||
.withStackTraceContaining(ReceiveFlow::class.java.name) // Make sure the stack trace is that of the receiving flow
|
.withStackTraceContaining(ReceiveFlow::class.java.name) // Make sure the stack trace is that of the receiving flow
|
||||||
.withStackTraceContaining("Received counter-flow exception from peer")
|
.withStackTraceContaining("Received counter-flow exception from peer ${bob.name}")
|
||||||
bobNode.database.transaction {
|
bobNode.database.transaction {
|
||||||
assertThat(bobNode.internals.checkpointStorage.checkpoints()).isEmpty()
|
assertThat(bobNode.internals.checkpointStorage.checkpoints()).isEmpty()
|
||||||
}
|
}
|
||||||
@ -630,6 +630,7 @@ class FlowFrameworkTests {
|
|||||||
Notification.createOnNext(ReceiveFlow.START_STEP),
|
Notification.createOnNext(ReceiveFlow.START_STEP),
|
||||||
Notification.createOnError(receiveFlowException)
|
Notification.createOnError(receiveFlowException)
|
||||||
)
|
)
|
||||||
|
assertThat(receiveFlowException).hasStackTraceContaining("Received unexpected counter-flow exception from peer ${bob.name}")
|
||||||
|
|
||||||
assertSessionTransfers(
|
assertSessionTransfers(
|
||||||
aliceNode sent sessionInit(ReceiveFlow::class) to bobNode,
|
aliceNode sent sessionInit(ReceiveFlow::class) to bobNode,
|
||||||
|
Loading…
Reference in New Issue
Block a user