Цепочки исключений в GraalVM - PullRequest
1 голос
/ 02 мая 2019

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

}
...