diff --git a/src/commonMain/kotlin/spp.protocol/artifact/exception/LiveStackTrace.kt b/src/commonMain/kotlin/spp.protocol/artifact/exception/LiveStackTrace.kt index ce3627e7..89001c99 100644 --- a/src/commonMain/kotlin/spp.protocol/artifact/exception/LiveStackTrace.kt +++ b/src/commonMain/kotlin/spp.protocol/artifact/exception/LiveStackTrace.kt @@ -77,15 +77,36 @@ class LiveStackTrace( private val pythonFrameRegex = Regex( " {2}File \"(.+)\", line ([0-9]+), in (.+)\\n {4}(.+)" ) + private val nodeFrameRegex = Regex( + "at (.+) \\((.+):([0-9]+):([0-9]+)\\)" + ) fun fromString(data: String): LiveStackTrace? { return when { + nodeFrameRegex.containsMatchIn(data) -> extractNodeStackTrace(data) frameRegex.containsMatchIn(data) -> extractJvmStackTrace(data) pythonFrameRegex.containsMatchIn(data) -> extractPythonStackTrace(data) else -> null } } + private fun extractNodeStackTrace(data: String): LiveStackTrace { + val elements = mutableListOf() + for (el in nodeFrameRegex.findAll(data)) { + val method = el.groupValues[1] + + val file = el.groupValues[2] + val line = el.groupValues[3].toInt() + val column = el.groupValues[4].toInt() + + elements.add(LiveStackTraceElement(method, "$file:$line", column)) + } + val firstLine = data.split("\n").first() + val exceptionType = firstLine.split(":").firstOrNull() ?: "n/a" + val message = firstLine.split(": ").drop(1).firstOrNull() ?: "n/a" + return LiveStackTrace(exceptionType, message, elements) + } + private fun extractPythonStackTrace(data: String): LiveStackTrace { val elements = mutableListOf() for (el in pythonFrameRegex.findAll(data).toList().reversed()) { diff --git a/src/commonMain/kotlin/spp.protocol/artifact/exception/LiveStackTraceElement.kt b/src/commonMain/kotlin/spp.protocol/artifact/exception/LiveStackTraceElement.kt index 87b7a070..6ceca1b5 100644 --- a/src/commonMain/kotlin/spp.protocol/artifact/exception/LiveStackTraceElement.kt +++ b/src/commonMain/kotlin/spp.protocol/artifact/exception/LiveStackTraceElement.kt @@ -30,6 +30,7 @@ import spp.protocol.instrument.variable.LiveVariable data class LiveStackTraceElement( val method: String, val source: String, + val column: Int? = null, val variables: MutableList = mutableListOf(), var sourceCode: String? = null ) { diff --git a/src/jvmTest/kotlin/spp/protocol/artifact/trace/LiveStackTraceTest.kt b/src/jvmTest/kotlin/spp/protocol/artifact/trace/LiveStackTraceTest.kt index 4b4a9f9a..9bc29313 100644 --- a/src/jvmTest/kotlin/spp/protocol/artifact/trace/LiveStackTraceTest.kt +++ b/src/jvmTest/kotlin/spp/protocol/artifact/trace/LiveStackTraceTest.kt @@ -43,4 +43,16 @@ class LiveStackTraceTest { assertEquals(23, stackTrace!!.elements.size) assertEquals(16, stackTrace.getElements(true).size) } + + @Test + fun parseNodeJsStackTrace() { + val stackTrace = LiveStackTrace.fromString( + Resources.toString(Resources.getResource("nodejsStackTrace.txt"), Charsets.UTF_8) + ) + assertNotNull(stackTrace) + assertEquals(stackTrace!!.exceptionType, "Error") + assertEquals(stackTrace.message, "Something unexpected has occurred.") + assertEquals(8, stackTrace.elements.size) + assertEquals(8, stackTrace.getElements(true).size) + } } diff --git a/src/jvmTest/kotlin/spp/protocol/marshall/ProtocolMarshallerTest.kt b/src/jvmTest/kotlin/spp/protocol/marshall/ProtocolMarshallerTest.kt index 62533713..f99944de 100644 --- a/src/jvmTest/kotlin/spp/protocol/marshall/ProtocolMarshallerTest.kt +++ b/src/jvmTest/kotlin/spp/protocol/marshall/ProtocolMarshallerTest.kt @@ -134,6 +134,7 @@ class ProtocolMarshallerTest { LiveStackTraceElement( "method", "source", + null, mutableListOf( LiveVariable( "name", @@ -155,6 +156,7 @@ class ProtocolMarshallerTest { LiveStackTraceElement( "method", "source", + null, mutableListOf( LiveVariable( "name", diff --git a/src/jvmTest/resources/nodejsStackTrace.txt b/src/jvmTest/resources/nodejsStackTrace.txt new file mode 100644 index 00000000..de9fd926 --- /dev/null +++ b/src/jvmTest/resources/nodejsStackTrace.txt @@ -0,0 +1,10 @@ +Error: Something unexpected has occurred. + at main (c:\Users\Me\Documents\MyApp\app.js:9:15) + at Object. (c:\Users\Me\Documents\MyApp\app.js:17:1) + at Module._compile (module.js:460:26) + at Object.Module._extensions..js (module.js:478:10) + at Module.load (module.js:355:32) + at Function.Module._load (module.js:310:12) + at Function.Module.runMain (module.js:501:10) + at startup (node.js:129:16) + at node.js:814:3