graaljs icon indicating copy to clipboard operation
graaljs copied to clipboard

HostException javascript line number

Open dfjhunt opened this issue 3 years ago • 2 comments

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 avatar Nov 23 '21 14:11 dfjhunt

@dfjhunt thanks for reporting the issue, please share a reproducer

munishchouhan avatar Nov 24 '21 05:11 munishchouhan

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();
	}
}

dfjhunt avatar Nov 29 '21 20:11 dfjhunt