GraalVM中的异常链 [英] Exception chains in GraalVM

查看:285
本文介绍了GraalVM中的异常链的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用GraalVM执行JavaScript文件,但是在处理异常时遇到了麻烦.我的JS代码使调用返回到Java,如果从那些Java方法之一中抛出异常,那么我会丢失原因链.

I'm using GraalVM to execute JavaScript files, but i'm having trouble with exception handling. My JS code makes calls back into Java, and if an exception is thrown from one of those Java methods then i lose the cause-chain.

public class Example {
    public static void doSomething() {
        throw new RuntimeException("Example", new RuntimeException("Some nested exception"));
    }
}

// --------------

var Example = Java.type("ex.Example");
function f() {
    Example.doSomething();
}

// -------------

String src = ... 
Source s = Source.newBuilder("js", src, "example").build();
try {
    context.eval(s);
} catch (PolyglotException e) {
    e.printStackTrace(); // This only prints the PolyglotException with the message "Example"
}

发生这种情况的原因是,Graal/Truffle生成了HostException的实例,该实例具有不调用super(e)的构造函数,它将其分配给用于获取消息的内部字段,而没有其他任何内容.这似乎是故意进行的,但我不明白原因.是安全问题吗?你能想到我可以改变这种行为的一种方式吗?我非常想在日志中找到引起异常的完整原因,但是此刻在HostException处停止,该异常通常只显示"A"之类的内容(例如,如果错误是NoSuchElementException("A"))

The reason this happens is because Graal/Truffle makes an instance of HostException, which has a constructor that doesn't call super(e), it assigns it to an internal field that's used to get the message and nothing else. It seems to have been done intentionally, but i don't understand the reason. Is it a security concern? Can you think of a way i can change this behaviour? I would very much like to have the full cause of the exception available in my logs, but at the moment it stops at the HostException, which often just says something like "A" (eg. if the original cause of the error was a NoSuchElementException("A"))

final class HostException extends RuntimeException implements TruffleException {

    private final Throwable original;

    HostException(Throwable original) {
        this.original = original;
    }

    Throwable getOriginal() {
        return original;
    }

    @Override
    public String getMessage() {
        return getOriginal().getMessage();
    }

    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }

    public Node getLocation() {
        return null;
    }

    public boolean isCancelled() {
        return getOriginal() instanceof InterruptedException;
    }

}

推荐答案

我遇到了同样的问题,结果发现JS错误具有以下功能:

I've faced the same issue and it turned out, that JS Error has the following functions:

printStackTrace: [Function],
fillInStackTrace: [Function],
getCause: [Function],
initCause: [Function],
toString: [Function],
getMessage: [Function],
getLocalizedMessage: [Function],
getStackTrace: [Function],
setStackTrace: [Function],
addSuppressed: [Function],
getSuppressed: [Function]

例如,

printStackTrace打印Java堆栈跟踪:

printStackTrace, for example, prints java stack trace:

try {
    Java.type('ClassWithException').throwRuntimeEx();
} catch (e) {
    console.log(e.printStackTrace())
}

给出以下内容:

java.lang.RuntimeException: Example message
at ex.ClassWithException.throwRuntimeEx(ClassWithException.java:6)
at com.oracle.truffle.polyglot.HostMethodDesc$SingleMethod$MHBase.invokeHandle(HostMethodDesc.java:269)
at com.oracle.truffle.polyglot.HostMethodDesc$SingleMethod$MHBase.invoke(HostMethodDesc.java:261)
at com.oracle.truffle.polyglot.HostExecuteNode$1.executeImpl(HostExecuteNode.java:776)
at com.oracle.truffle.polyglot.GuestToHostRootNode.execute(GuestToHostRootNode.java:87)
at org.graalvm.compiler.truffle.runtime.OptimizedCallTarget.callProxy(OptimizedCallTarget.java:328)
...
at com.oracle.truffle.polyglot.PolyglotValue$InteropValue.execute(PolyglotValue.java:2008)
at org.graalvm.polyglot.Value.execute(Value.java:338)
at com.oracle.truffle.trufflenode.GraalJSAccess.isolateEnterPolyglotEngine(GraalJSAccess.java:2629)
Caused by: java.lang.RuntimeException: Inner exception
... 245 more

这篇关于GraalVM中的异常链的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆