Problems with SyntaxError construction

Tim Fox timvolpe at gmail.com
Fri Feb 20 09:41:07 UTC 2015


HI Sundar -

On 20/02/15 08:09, A. Sundararajan wrote:
> * SyntaxError constructor accepting extra arguments apart from message 
> is not as per ECMAScript standard. That one is Firefox/Mozilla 
> specific extension. We try to *add* properties, functions for 
> extension - try not to modify/extend standard defined functions, 
> constructors.
>
> * User can fileName, lineNumber and columnNumber of constructed 
> SyntaxError instance.
>
> * On the java side, the NashornException and ScriptException's file, 
> line, column use the actual throw point from the script source. While 
> this can read the values from SyntaxError or any Error for that 
> matter, there is a problem. fileName, lineNumber, columnNumber could 
> be set to any value in script. These have to be converted to String, 
> int, int respectively. Conversion means calling [[DefaultValue]] with 
> String, Number hint - which is calling out to script code. This 
> process can itself throw exception!! All this may destroy info. on 
> where exactly the underlying exception was thrown.
>
> * There is clear workaround. Script code can always read SyntaxError 
> instance's fileName, lineNumber etc. - which can be set to anything 
> post construction. Java code can get underling ECMA error instance via 
> NashornException.getEcmaError - which would return a 
> ScriptObjectMirror. Java code can call 
> ScriptObjectMirror.getMember("fileName") etc. to retrieve properties 
> set by user's script.

I've tried what you suggest, it seems to work (ish), but I end up with 
seriously grungy code that relies on casting and non public APIs that (I 
guess) could be changed without warning in any release, so I don't think 
I'd be happy doing this in Vert.x. Here's an example:

(Yikes!)

https://gist.github.com/purplefox/003fae1e32fd44368ffa

So.... rewinding a bit here. The only reason I find myself shaving this 
particular Yak is because syntax errors thrown from evals() aren't 
reported by Nashorn with the fileName and lineNumber of the _eval_, 
instead they are reported with the fileName/lineNumber of where the eval 
was executed.

I mentioned this in a previous post, but here is the gist again that 
demonstrates the issue:

https://gist.github.com/purplefox/7ba0d87d2d1670b871a4

This means I have to manually catch SyntaxErrors in our require() 
implementation. Fill in the correct fileName, lineNumber etc and rethrow 
as new SyntaxError instances. But, as we discussed in this thread, that 
doesn't seem to work easily as I can't set fileName, lineNumber etc when 
constructing an instance in Nashorn, and if I set it afterwards those 
values aren't visible in Java (at least not in a portable way that 
doesn't rely on hacky reliance on non public APIs). If I don't do this, 
our users see a pretty useless error message when there's a syntax error 
in their module and it all leads to a very poor user experience.

Imho, a better way to solve this would be for Nashorn to create syntax 
error instances when doing evals() that properly reflect the lineNumber 
and fileName of the _eval_ not of the place the eval was executed. This 
seems a far more intuitive way to do it and it would be consistent with 
the way other Error types are thrown from code in evals (e.g. TypeError, 
RangeError etc) which *do* reflect the correct line in the eval where 
the error occurred. Fundamentally a user is not going to care about the 
lineNumber where the eval was executed, they want to know where in the 
actual code the syntax error is - that's the useful information which is 
currently being obscured.

So, any chance of changing/fixing the current behaviour? Doing that 
would mean I wouldn't have to little our code with piles of Yak hair 
trying to get the important information out of private classes, and I 
think it would lead to a better and more intuitive user experience :)





>
> Hope this helps,
> -Sundar
>
> On Wednesday 18 February 2015 08:29 PM, Tim Fox wrote:
>> Hi all,
>>
>> I've started a new thread for this, so as not to clutter the previous 
>> thread on exceptions.
>>
>> I've come across a possible issue with creating SyntaxError objects 
>> (and potentially other exceptions although I haven't tested them).
>>
>> https://gist.github.com/purplefox/dfe30a38098c1708e24b
>>
>> In the above gist I create a SyntaxError specifying message, 
>> fileName, and lineNumber.
>>
>> However fileName and lineNumber appear to be ignored, and instead the 
>> SyntaxError fileName and lineNumber are set to the fileName of the 
>> file where it was created and the lineNumber of the creation.
>>
>> I'm not sure if I'm doing something wrong, but according to 
>> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError 
>> I should be able to create SyntaxError objects like this.
>>
>> There appears to be a further issue. If I then throw the syntax error 
>> from the JS script, and catch it in Java like this:
>>
>> try {
>>       engine.eval(script);
>>     } catch (ScriptException e) {
>>       System.out.println("message:" + e.getMessage());
>>       System.out.println("fileName:" + e.getFileName());
>>       System.out.println("lineNumber:" + e.getLineNumber());
>> }
>>
>> Then the message, fileName and lineNumber always correspond to place 
>> where the object was created, not to the subsequently set values.
>>
>> In other words, I can't figure out a way of creating a SyntaxError 
>> object in JS with my own values of fileName and lineNumber and have 
>> those values available in Java when caught.
>>
>> Any ideas from the experts? :)
>>
>>
>



More information about the nashorn-dev mailing list