Я использую 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;
}
}