On 18/02/15 13:33, A. Sundararajan wrote:
So, did you fix "// #sourceURL" to //# sourceURL" ? Note on the whitespace: no whitespace between '//' and '#' and single whitespace after '#' ?

Bingo, that worked :)

So I now have exceptions thrown from evals showing correct lineNumber, fileName and stack for all exceptions apart from SyntaxError.

I've created another example here:

https://gist.github.com/purplefox/f99ad4c78d246d2d6aee

In this example, the eval has a Syntax Error (e.g. the user is trying require a module with a syntax error in it).

What I see is that the caught exception corresponds to where the eval() was _executed_, not to the place in the eval code where the syntax error actually is.

Interestingly the correct information *is* available if I do a bit of digging - two references deep from the caught exception there's the exception that we're actually interested in with the correct lineNumber, (but not correct fileName).

I'd expect the caught exception to correspond to the actual SyntaxError in the code not to where the eval was invoked - this would be consistent with how the other error types are handled, and it would be a lot more useful for the user, as what they want to know is where in their code the problem actually is.


Release notes page here says the fix is in 8u20. http://www.oracle.com/technetwork/java/javase/2col/8u20-bugfixes-2257730.html. Bug id is http://bugs.java.com/view_bug.do?bug_id=8032068

-Sundar

On Wednesday 18 February 2015 06:58 PM, Tim Fox wrote:
On 18/02/15 13:13, A. Sundararajan wrote:

Hi Tim,

It was added in 8u20 if I recall right.

jjs -version
nashorn 1.8.0_40
jjs>
jjs> eval("f() //# sourceURL=t.js")
t.js:1 ReferenceError: "f" is not defined
jjs> eval("g() //@ sourceURL=g.js")
g.js:1 ReferenceError: "g" is not defined

I think your file has "// #sourceURL=wibble.js". Please try changing it as "//# sourceFile=wibble.js"

Ok, I am confused now... I have tried both #sourceURL (which most of the google hits say to use) and #sourceFile and neither seem to work ;)

I've also tried @sourceURL which some other links say to use. (Yay for consistency ;) )

Nothing seems to work so far.

I am using nashorn 1.8.0_25 which is the latest version in the production Oracle JDK afaict. Do I have to use OpenJDK to get these changes? I don't think this will be an option as most of users use the Oracle JDK.


See also: https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Debug_eval_sources

-Sundar

On Wednesday 18 February 2015 06:14 PM, Tim Fox wrote:
Hi Sundar,

I tried the sourceURL trick:

https://gist.github.com/purplefox/60619067006c3cc3eaee

But it doesn't seem to work. I suspect because the parsing of the eval fails before it gets to the last line (?) :(

I'm going to give a go with load()...

On 18/02/15 10:11, A. Sundararajan wrote:
you can use

1) "load" from object - object with name and script properties.

2) or use 'eval' naming // #sourceURL comment

as mentioned here:

http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-July/003174.html

Can code for body of module function be something like "eval(readScriptAsText() + "\n// #sourceURL=" + name)" ?

Hope this helps,
-Sundar

On Wednesday 18 February 2015 03:30 PM, Tim Fox wrote:
I've added a simple reproducer that you can run in the repl:

https://gist.github.com/purplefox/b03a2a6263c26e3206da

Another observation is that line number is reported as 6, when it should be 5 (assuming the first line is line 1 which is normal convention afaik)

On 18/02/15 09:40, Tim Fox wrote:
Hi all,

I'm currently using a CommonJS/npm modules require implementation (npm-jvm) with Nashorn.

Roughly, the way it works (and I'm sure you're already familiar with this technique) is it takes the JavaScript module and wraps it in a Function object:

var body = readScriptAsText();
var args = ['exports', 'module', 'require', '__filename', '__dirname'];
var func = new Function(args, body);
func.apply(module, [module.exports, module, module.require, module.filename, dir]); // Execute it - this works fine

Now let's say the actual module (foomodule.js) we are loading contains this:

module.exports = function() {
    var num = 234;
    num.substr(1, 1); // Will throw TypeError here
}

I.e. it simply exports a function, which will throw a TypeError when it's executed.

When the exported function is executed it does indeed throw a TypeError:

var f = require("foomodule");

f(); // Throws TypeError

Unfortunately the fileName field of the TypeError is set to "<function>" not to "foomodule.js", which is unfriendly for the user.

This is understandable as the Function object which wraps the module doesn't know about "foomodule.js".

So.. my question is.. how do I tell the Function object that the "filename" it should use when exceptions are thrown from it is "foomodule.js"?

I have tried the following and none work:

var func = new Function(args, body);
func.name = "foomodule.js";
func.fileName = "foomodule.js";
func.displayName = "foomodule.js";

Any insights would be greatly appreciated.











Reply via email to