1

我一直在用 kotlin-js 为应用程序编写简单的 Web 前端,并面临异常处理的问题。如我所见,没有 API 可以获取异常堆栈跟踪:https ://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-throwable/index.html 是这样吗?如果是,可能有人知道一些库或片段可以从 Throwable 对象中获取堆栈跟踪吗?

目前,我有一些解决方法:

import kotlin.browser.window

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

控制台输出为:

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"
}

这里console.log(Throwable)公开了底层的 JavaScript 对象属性,有stack一个,但它指向 JavaScript 代码,如果没有将源映射回 kotlin,就很难使用。

UPD:似乎stack不是标准的异常属性,而是现代浏览器的常见属性。

4

3 回答 3

1

从 Kotlin 1.4 开始,stdlib 包含两个用于此目的的扩展 fun Throwable.stackTraceToString()
fun Throwable.printStackTrace()

使用这些我们可以写

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

于 2020-11-11T11:54:51.727 回答
0

只需将您的更改console.logconsole.error

import kotlin.browser.window

fun main() {
    window.onload = {
        try {
            throw RuntimeException()
        } catch (e: Throwable) {
            console.error(e) // change here
            throw e
        }
    }
}
于 2019-07-11T09:09:00.450 回答
0

不完美,不标准,但它有效。
它还处理 Firefox 中的源映射,所以我得到了正确的文件名和行号:

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)
    }
}
于 2020-06-16T04:57:34.727 回答