如何只显示错误而不显示调用堆栈跟踪?

问题描述 投票:0回答:2

我正在设计一个简单的玩具解释器,我有一个自定义异常,如下所示:

class ValError(varName: String) : Exception("$varName is val, cannot reassign.")

问题是,当它被抛出时,它打印出整个调用堆栈跟踪,如下所示:

ValError: foo is val, cannot reassign.
    at com.github.me.dynamik.interpreter.Environment.get(Environment.kt:62)
    at com.github.me.dynamik.interpreter.TreeWalker.visitVariableExpr(TreeWalker.kt:154)
    at com.github.me.dynamik.expressions.VariableExpr.evaluateBy(Expression.kt:57)

但我只想打印出第一行

ValError: foo is val, cannot reassign.

我该如何做到这一点?

java exception kotlin stack-trace traceback
2个回答
2
投票

简短的回答:抓住异常,并打印其message字段。您可以在顶级函数中的try ... catch块中执行此操作,或者(更好)在UncaughtExceptionHandler中执行此操作。

长期无聊的回答:

异常将从每个函数传递给它的调用者,直到找到一个带有封闭的try ... catch块的异常。

所以一种方法是自己捕捉异常,例如:

fun main() {
    try {
        // All your top-level code here…
    } catch (x: Exception) {
        System.err.println(x.message)
    }
}

如果您正在使用日志框架,那么您当然可以使用它。

如果没有封闭的try ... catch,它将调用线程的UncaughtExceptionHandler - 或者,如果线程没有一个,它的ThreadGroup的一个,或者失败,the default one

如果您没有提供默认值,系统会调用其printStackTrace()方法,该方法将异常消息及其所有回溯打印到标准错误流 - 这就是您看到问题中显示的跟踪的原因。

所以另一种方法是将UncaughtExceptionHandler设置为其中一个级别,例如:

Thread.setDefaultUncaughtExceptionHandler { t, x ->
    System.err.println(x.message)
}

这样更安全,因为它适用于所有线程。

如果您正在编写一个仅使用单个线程的简单应用程序,那么可以直接在顶级方法中捕获异常。但是如果您正在编写使用GUI工具包或Web框架的东西,或者使用协同程序或其他执行框架,或者手动启动任何线程,那么可能会有其他线程在运行。这有两个影响:

  • 首先,您将无法访问这些线程的顶级方法,因此您将无法捕获那些异常。因此,UncaughtExceptionHandler是唯一的方式。 (默认值最安全,因为您可能无法访问线程,甚至无法访问ThreadGroup。)
  • 其次,虽然具有异常的线程将停止运行,但任何其他线程都不会。因此JVM不会关闭,其他线程将继续运行,不知道。这会使您的应用处于不一致的状态,这可能是灾难性的:您可能最终排队等待但从未运行的作业,或其他线程停止等待数据,或请求无人接听,或者几乎任何事情取决于您的应用程序是什么结构化和哪个线程死亡。而且由于JVM仍在继续,系统级监视器或服务管理器不会知道有什么问题。

因此,在记录异常之后,在某些情况下,处理程序关闭整个应用程序可能是一个非常好的主意。

(顺便说一句,第三种方法是使用自定义Exception并覆盖其printStackTrace()方法仅打印消息。但这不是一个好主意;它会破坏该方法的意图,这可能会导致任何使用的问题的各种问题它。)


0
投票

使用try..catch

科特林

try {
  // perform tasks
    throw ValError("x")
} catch (e: ValError) {
    println(e.message)
}

Java的

try{
    // perform task
    throw new ValError("x")
}
catch(ValError e){
     System.out.println(e.getMessage()); 
}
© www.soinside.com 2019 - 2024. All rights reserved.