mirror of
https://github.com/corda/corda.git
synced 2024-12-19 21:17:58 +00:00
EG-65 - Improved error reporting on stdout (#5962)
I modified the `ErrorCodeRewritePolicy` to concatenate all the error messages of the exception's cause chain. The code will start from the throwable being passed to the logger and concatenate its error message with the one in its cause and proceed recursively until it finds an exception with no cause or it detects a loop (an exception already encountered in the traversal). This should provide customers with more information about errors without having to look at the logs (that should still remain the primary source of information)
This commit is contained in:
parent
4c492a797b
commit
98e9b1caa6
@ -4,11 +4,37 @@ import org.apache.logging.log4j.Level
|
||||
import org.apache.logging.log4j.message.Message
|
||||
import org.apache.logging.log4j.message.SimpleMessage
|
||||
import java.util.*
|
||||
//Returns an iterator that traverses all the exception's cause chain stopping in case of loops (an exception caused by itself)
|
||||
fun Throwable.walkExceptionCausedByList() : Iterator<Throwable> {
|
||||
val self = this
|
||||
return object : Iterator<Throwable> {
|
||||
private var cursor : Throwable? = self
|
||||
private val knownThrowables = mutableSetOf<Throwable>()
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return cursor != null
|
||||
}
|
||||
|
||||
override fun next(): Throwable {
|
||||
val result = cursor
|
||||
val cause = cursor?.cause
|
||||
cursor = if(cause != null && knownThrowables.add(cause)) {
|
||||
cause
|
||||
} else {
|
||||
null
|
||||
}
|
||||
return result!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Message.withErrorCodeFor(error: Throwable?, level: Level): Message {
|
||||
|
||||
return when {
|
||||
error != null && level.isInRange(Level.FATAL, Level.WARN) -> CompositeMessage("$formattedMessage [errorCode=${error.errorCode()}, moreInformationAt=${error.errorCodeLocationUrl()}]", format, parameters, throwable)
|
||||
error != null && level.isInRange(Level.FATAL, Level.WARN) -> {
|
||||
val message = error.walkExceptionCausedByList().asSequence().mapNotNull(Throwable::message).joinToString(" - ")
|
||||
CompositeMessage("$message [errorCode=${error.errorCode()}, moreInformationAt=${error.errorCodeLocationUrl()}]", format, parameters, throwable)
|
||||
}
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,59 @@
|
||||
package net.corda.commmon.logging
|
||||
|
||||
import net.corda.common.logging.walkExceptionCausedByList
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.junit.runners.Parameterized
|
||||
|
||||
@RunWith(Parameterized::class)
|
||||
class WalkExceptionCausedByListTest(@Suppress("UNUSED_PARAMETER") testTitle: String, private val e: Throwable, private val expectedExceptionSequence: List<Throwable>) {
|
||||
|
||||
private class TestThrowable(val id : Int, cause : Throwable?) : Throwable(cause) {
|
||||
override fun toString(): String {
|
||||
return "${this.javaClass.simpleName}(${this.id})"
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@Parameterized.Parameters(name = "{0}")
|
||||
fun data(): Collection<Array<Any>> {
|
||||
val field = Throwable::class.java.getDeclaredField("cause")
|
||||
field.isAccessible = true
|
||||
return listOf(
|
||||
run {
|
||||
val e = TestThrowable(0, null)
|
||||
arrayOf("Simple exception with no cause", e, listOf(e))
|
||||
},
|
||||
run {
|
||||
var e: TestThrowable? = null
|
||||
val exceptions = (0 until 10).map {
|
||||
e = TestThrowable(it, e)
|
||||
e
|
||||
}
|
||||
arrayOf("Exception with cause list", e!!, exceptions.asReversed())
|
||||
},
|
||||
run {
|
||||
val e = TestThrowable(0, null)
|
||||
field.set(e, e)
|
||||
arrayOf("Exception caused by itself", e, listOf(e))
|
||||
},
|
||||
run {
|
||||
val stack = mutableListOf<TestThrowable>()
|
||||
var e: TestThrowable? = null
|
||||
for(i in 0 until 10) {
|
||||
e = TestThrowable(i, stack.lastOrNull())
|
||||
stack.add(e!!)
|
||||
}
|
||||
field.set(stack[0], stack[4])
|
||||
arrayOf("Exception with loop in cause list", e!!, stack.asReversed())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@Test(timeout = 1000)
|
||||
fun test() {
|
||||
Assert.assertEquals(expectedExceptionSequence, e.walkExceptionCausedByList().asSequence().toList())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user