2

I've been writing simple web-frontend for application with kotlin-js and faced with a problem of exception handling. As I see, there is no API to get exception stacktrace: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html Is it so? If it is, may be anyone know some library or snippets to get stacktrace out of Throwable object?

Currently, I've got some workaround for this:

import kotlin.browser.window

fun main() {
    window.onload = {
        try {
            throw RuntimeException()
        } catch (e: Throwable) {
            console.log(e)
            throw e
        }
    }
}

Console output is:

Object { 
"message_8yp7un$_0": null, 
"cause_th0jdv$_0": null, 
"stack": "captureStack@http://localhost:9080/js/kotlin.js:1767:27\nException@http://localhost:9080/js/kotlin.js:3244:14\nRuntimeException@http://localhost:9080/js/kotlin.js:3255:17\nRuntimeException_init@http://localhost:9080/js/kotlin.js:3261:24\nmain$lambda@http://localhost:9080/js/web-client.js:34:13\n",
"name": "RuntimeException"
}

Here, console.log(Throwable) exposes underlying JavaScript object properties, and there is stack one, but it points to JavaScript code, that is hard to use without source mapping back to kotlin.

UPD: it seems like stack is not standard exception property, but common one for modern browsers.

3 Answers 3

4

Since Kotlin 1.4 the stdlib contains two extensions for this exact purpose fun Throwable.stackTraceToString()
fun Throwable.printStackTrace()

Using these we can write

    window.onload = {
        try {
            throw RuntimeException()
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }

Sign up to request clarification or add additional context in comments.

Comments

1

Not perfect, not standard, but it works.
It also handles the source map in Firefox, so I get proper file names and line numbers:

try {
    throw IllegalStateException("ops...")
} 
catch (ex : Throwable) {
    val stack = ex.asDynamic().stack
    if (stack is String) {
        val error = js("Error()")
        error.name = ex.toString().substringBefore(':')
        error.message = ex.message?.substringAfter(':')
        error.stack = stack
        console.error(error)
    } else {
        console.log(ex)
    }
}

Comments

0

Just change your console.log to console.error

import kotlin.browser.window

fun main() {
    window.onload = {
        try {
            throw RuntimeException()
        } catch (e: Throwable) {
            console.error(e) // change here
            throw e
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.