我正在使用GraalVM执行JavaScript文件,但是在处理异常时遇到了麻烦。我的JS代码使调用返回到Java,如果从那些Java方法之一中抛出异常,那么我会丢失原因链。
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")
)
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;
}
}
答案 0 :(得分:0)
我也遇到过同样的问题,事实证明,JS错误具有以下功能:
printStackTrace: [Function],
fillInStackTrace: [Function],
getCause: [Function],
initCause: [Function],
toString: [Function],
getMessage: [Function],
getLocalizedMessage: [Function],
getStackTrace: [Function],
setStackTrace: [Function],
addSuppressed: [Function],
getSuppressed: [Function]
例如, printStackTrace
打印Java堆栈跟踪:
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