Skip to content

Async functions should be able to throw exceptions #187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ignatandrei opened this issue Apr 15, 2020 · 16 comments
Closed

Async functions should be able to throw exceptions #187

ignatandrei opened this issue Apr 15, 2020 · 16 comments

Comments

@ignatandrei
Copy link

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

new Date('foo-bar')

)

@cpcallen
Copy link
Collaborator

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.

  • Are you asking how to catch an exception thrown by a built-in? They may be caught in the usual way:
try {
  new Array(-1); 
} catch (e) {
  // e is RangeError: Invalid array length
}
  • Are you asking how to detect if a piece of interpreted code threw an uncaught exception? This can be done by putting a try/catch around the call to .step or .run; an unhandled Error object within the interpreter will be converted into the corresponding native Error type and thrown; other values will be converted to a string and thrown as a string value.
  • Are you curious about how exception handling is implemented internally in JS Interpreter? If so, there are many details but the main piece of machinery is the Interpreter.prototype.unwind method. But the implementation details should not be relevant to you unless you are proposing to modify JS Interpreter itself.

@ignatandrei
Copy link
Author

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
Copy link
Collaborator

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

@ignatandrei
Copy link
Author

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 ignatandrei/NETCoreBlockly#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 cpcallen changed the title question error handling ? Async functions should be able to throw exceptions Apr 27, 2020
@cpcallen
Copy link
Collaborator

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.

@cpcallen cpcallen reopened this Apr 27, 2020
@ignatandrei
Copy link
Author

ignatandrei commented Apr 27, 2020

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
Copy link
Author

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
Copy link
Collaborator

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
Copy link
Author

ignatandrei commented Apr 28, 2020

I have copied from 68bb747
( and I was thinking that Interpreter, from Interpreter.NONENUMERABLE_DESCRIPTOR 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 acorn_interpreter.js (92,39)

Could you please give a hint?

@cpcallen
Copy link
Collaborator

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
Copy link
Author

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
    intercept errors in wrapper XHR functions ignatandrei/NETCoreBlockly#7

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

@cpcallen
Copy link
Collaborator

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
Copy link
Author

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
Copy link
Collaborator

Take both from the root of the site here ?

Yes.

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

Yes.

@ignatandrei
Copy link
Author

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
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants