graaljs
graaljs copied to clipboard
HostException javascript line number
I have some javascript code that calls a ProxyExecutable which throws a RuntimeException. I can catch that exception in javascript and see as much as I need of the Java exception but it doesn't seem to attach any javascript details. Specifically, I would like to get the javascript line number of the line that called the ProxyExecutable.
@dfjhunt thanks for reporting the issue, please share a reproducer
I put in two examples that give the line number in the stack trace and then the third example where the exception is thrown by the Java code where there is no javascript information in the stack trace.
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
import org.graalvm.polyglot.proxy.ProxyExecutable;
public class ExceptionExample implements ProxyExecutable {
public void doExample() {
try (Context context = Context.newBuilder("js").allowHostAccess(true).build()) {
//Put the ProxyExecutable into context
context.getBindings("js").putMember("runExample", this);
//Just an empty Java object to get an exception in the second example
context.getBindings("js").putMember("emptyObject", new Object());
//The stack has the javascript line number, looks like:
//Error: testError
// at testError (Unnamed:4:10)
context.eval("js", "function testError() { \r\n"
+ " try{ \r\n"
+ " console.log('starting error test'); \r\n"
+ " throw new Error('testError'); \r\n"
+ " } catch(e) { \r\n"
+ " console.log('exception: '+e); \r\n"
+ " console.log('properties: '+Object.getOwnPropertyNames(e));\r\n"
+ " console.log(e.stack); \r\n"
+ " } \r\n"
+ "}");
//The stack has the javascript line number, looks like:
//TypeError: invokeMember (foo) on java.lang.Object@1cfd1875 failed due to: Unknown identifier: foo
// at testGuestError (Unnamed:4:16)
context.eval("js", "function testGuestError() { \r\n"
+ " try{ \r\n"
+ " console.log('starting guest error test'); \r\n"
+ " emptyObject.foo() \r\n"
+ " } catch(e) { \r\n"
+ " console.log('exception: '+e); \r\n"
+ " console.log('properties: '+Object.getOwnPropertyNames(e));\r\n"
+ " console.log(e.stack); \r\n"
+ " } \r\n"
+ "}");
//The only "properties" logged here are Java Throwable methods and the stack trace
//is just the Java stack trace with no detail about the line number in the
//javascript code.
context.eval("js", "function testHostError() { \r\n"
+ " try{ \r\n"
+ " console.log('starting host error test'); \r\n"
+ " runExample(); \r\n"
+ " } catch(e) { \r\n"
+ " console.log('exception: '+e); \r\n"
+ " console.log('properties: '+Object.getOwnPropertyNames(e));\r\n"
+ " e.printStackTrace(); \r\n"
+ " } \r\n"
+ "}");
context.getBindings("js").getMember("testError").execute();
System.out.println("\n\n\n\n");
context.getBindings("js").getMember("testGuestError").execute();
System.out.println("\n\n\n\n");
context.getBindings("js").getMember("testHostError").execute();
}
}
public static void main(String args[]) {
ExceptionExample example = new ExceptionExample();
example.doExample();
}
@Override
public Object execute(Value... arguments) {
throw new ArrayIndexOutOfBoundsException();
}
}