NeilFraser / JS-Interpreter

A sandboxed JavaScript interpreter in JavaScript.
Apache License 2.0
1.98k stars 353 forks source link

Async functions should be able to throw exceptions #187

Closed ignatandrei closed 4 years ago

ignatandrei commented 4 years ago

I cannot figure how the interpreter is raising errors when something got wrong ( for example , a

new Date('foo-bar')

)

cpcallen commented 4 years ago

The expression new Date('foo-bar') does not throw any exception; instead it returns Date object with internal value NaN:

> (new Date('foo-bar')).valueOf()
<- NaN

Otherwise, I am not sure what you are asking.

ignatandrei commented 4 years ago

I have tried to put a catch block around .run. It did not catch the exception. I will be back with some example to run ( on Docker ;-) ) Thanks for you answer

cpcallen commented 4 years ago

Let me repeat myself: the expression new Date('foo-bar') does not throw any exception.

ignatandrei commented 4 years ago

Now I have a good example:

please go to https://netcoreblockly.herokuapp.com/blockly.html ( it is open source and generates blockly from WebAPI definition - not important now)

There is a link in the bottom of the page named https://github.com/ignatandrei/NETCoreBlockly/issues/7

It will generate some block that call an HTTP backend that throws an 500 error. You can find the XHR function that throws an error in blockly\BlocklyXHRWrapper.js function

How can I intercept this error with the Interpreter from blockly.html ?

Thanks Andrei

cpcallen commented 4 years ago

Oh, OK. You are asking about throwing exceptions, from async native functions, rather than catching them.

Async functions can throw exceptions, using the following procedure:

  1. Create an Error (or subclass) object by calling myInterpreter.createObject or .createObjectProto; call this error.
  2. Call myInterpreter.unwind(Interpreter.Completion.THROW, error, undefined)
  3. Set myInterpreter.paused_ = false
  4. And of course ensure that myInterpreter.run() will get called again, to resume execution.

Steps 1 and 4 will always be your responsibility, but steps 2 and 3 really ought to be provided by the JS Interpreter itself—for example, via #178.

ignatandrei commented 4 years ago

If I understand, I will write in my code:

let error= myInterpreter.createObject( { err: 'this is my error'})

Where an error to be raised , I call

myInterpreter.unwind(Interpreter.Completion.THROW, error, undefined)

This is all , right? I will try ASAP.( and thanks for the answer)

ignatandrei commented 4 years ago

I tried to copy the code from here:

var error = myInterpreter.createObject(interpreter.ERROR); myInterpreter.setProperty(error, 'message', req.status + req.statusText, Interpreter.NONENUMERABLE_DESCRIPTOR); callback(undefined, error);

but it gives me:

: Non object prototype Please help

cpcallen commented 4 years ago

Not sure where you're copying from, but it looks like your first line should read either

var error = myInterpreter.createObject(myInterpreter.ERROR)

or

var error = interpreter.createObject(interpreter.ERROR)

depending on the name of the variable containing your Interpreter instance.

ignatandrei commented 4 years ago

I have copied from https://github.com/NeilFraser/JS-Interpreter/pull/178/commits/68bb7471bae8be36e119866984fa00339371cb44 ( and I was thinking that Interpreter, from _Interpreter.NONENUMERABLEDESCRIPTOR in the code in the commit was a static singleton object ... sorry for the mistake)

And I have put now:

var error = myInterpreter.createObject(myInterpreter.ERROR); myInterpreter.setProperty(error, 'message', 'aaaaaaaaaaaaaa',// just for test myInterpreter.NONENUMERABLE_DESCRIPTOR); callback(undefined, error);

but it gives the error: _0: Non object prototype acorninterpreter.js (92,39)

Could you please give a hint?

cpcallen commented 4 years ago

And I have put now:

var error = myInterpreter.createObject(myInterpreter.ERROR);
myInterpreter.setProperty(error, 'message',
    'aaaaaaaaaaaaaa',// just for test
    myInterpreter.NONENUMERABLE_DESCRIPTOR);
callback(undefined, error);

but it gives the error: 0: Non object prototype acorn_interpreter.js (92,39)

Not sure what's going on here. The error message comes from createObjectPrototype, which is called by createObject, but the call to createObject in the above snippet looks fine now.

I note that you are using acorn_interpreter.js, but my patch in PR #178 is only against interpreter.js, so the callback you are invoking here only takes one argument. Still: that doesn't immediate explain the error. Can you get the full call stack for the error?

ignatandrei commented 4 years ago

1 .I do not know for sure if I want acorn_interpreter or interpreter. What are the differences ? Should I use interpreter ?

  1. The full stack: Uncaught Error: Non object prototype at u.q.h (acorn_interpreter.js:93) at u.q.ma (acorn_interpreter.js:92) at XMLHttpRequest.req.onreadystatechange (BlocklyXHRWrapper.js:41)

  2. For reproducing the error, please goto https://netcoreblockly.herokuapp.com/blockly.html , and press the link in the bottom of the page that says https://github.com/ignatandrei/NETCoreBlockly/issues/7

( and I can replace any js with what you want)

cpcallen commented 4 years ago

So, acorn_interpreter.js is acorn.js + interpreter.js, compiled (and minified) using Closure Compiler.

It won't have either my patch in #178 nor the .ERROR property needed for the code snippet to work. (Well, it will have ERROR, but renamed to some random short name.)

Use the uncompiled versions instead.

ignatandrei commented 4 years ago

Take both from the root of the site here ? https://github.com/NeilFraser/JS-Interpreter ? And what will be the order ? acorn, then interpreter ?

cpcallen commented 4 years ago

Take both from the root of the site here ?

Yes.

And what will be the order ? acorn, then interpreter ?

Yes.

ignatandrei commented 4 years ago

Now it does not work at all ( not even what it worked before) The error is: Object doesn't support property or method 'createPrimitive' interpreter.js (326,8)

Do you want to deploy to take a look? ( and thanks for your time)

ignatandrei commented 4 years ago

You can close. There is a mid - hack to solve it :register a function into the interpreter. Do not throw the error, call this global error handler