NeilFraser / JS-Interpreter

A sandboxed JavaScript interpreter in JavaScript.
Apache License 2.0
1.96k stars 352 forks source link

[QUESTION] How to throw exception from createAsyncFunction ? #247

Closed Tilican closed 1 year ago

Tilican commented 1 year ago

hey,

I'm using JS-Interpreter for custom scripting on my app :)

But i need to throw an exception from async :/

I try that

interpreter.setProperty(
      globalObject,
      'modules',
      interpreter.createAsyncFunction(
        async (moduleName, moduleMethod, moduleParamsP, callback) => {
          const modulesParams = interpreter.pseudoToNative(moduleParamsP)
          await new Promise(resolve => setTimeout(resolve, 1000))
          const test = Math.random()
          if (test > 1) {
            console.log(moduleName, moduleMethod, modulesParams)
            callback(`${moduleName + moduleMethod + modulesParams} => KAPPA`)
          } else {
            // callback(interpreter.createObject(interpreter.TYPE_ERROR, "TEST"))
            callback(interpreter.throwException(interpreter.TYPE_ERROR, 'Something went bad !'))
          }
        }
      )
    )

But i can't catch it with ...

const myCode = `
modules('hello', 'say', [1,3,"azezaee"]);

Math.random() >=  0.5
`

const myInterpreter = new JSInterpreter.Interpreter(myCode , initFunc)
  try {
    const run = () => {
      if (myInterpreter.run()) {
        setImmediate(run)
      } else {
        console.log('Result', myInterpreter.pseudoToNative(myInterpreter.value))
      }
    }
    run()
  } catch (e) {
    console.log('THIS IS AN ERROR', e)
  }

I got

hello say [ 1, 3, 'azezaee' ]
node:internal/process/promises:279
            triggerUncaughtException(err, true /* fromPromise */);
            ^

[TypeError: Something went bad !
  at code:1:0]

Thx :D

cpcallen commented 1 year ago

You should be catching the exception in the interpreted code, not in the code invoking the interpreter:

const myCode = `
try {
  modules('hello', 'say', [1,3,"azezaee"]);
} catch (e) {
  // handle e
}
`

Also, on this line:

        callback(interpreter.throwException(interpreter.TYPE_ERROR, 'Something went bad !'))

you do not need (and should not call) callback. As it happens, throwException actually throws an exception which means that callback will not actually be called, but if that were not the case it would still suffice to call throwException, and calling callback would actually cause unexpected and undesirable behaviour.