3

使用 JDK 6ScriptEngine机制,在“eval”或“invokeMethod”期间出现的任何问题或任何导致ScriptException被退回到调用 Java 环境的情况。据我通过实验和源代码阅读所知道的,当我的Javascript 代码想要抛出异常时,从 Javascript 中获取信息的最好方法就是抛出一个字符串。该字符串显示在ScriptException对象的“getMessage”返回值中。不漂亮。

似乎能够:

 if (somethingWrong) {
   throw { error: Errors.INVALID_SOMETHING, context: whatever() };
 }

来自 Javascript,然后 Java 代码可以以某种方式获取该对象。然而,我担心鉴于 RhinoScriptEngine包装器的当前实现,这是不可能的。但是,如果有人知道一个有效的技巧,我很乐意看到它。

4

3 回答 3

2

Rhino 对异常的支持确实很差,它们不像 Groovy 或 JRuby 等其他脚本引擎那样有用或有用。

为了帮助您调试问题,我认为您可以使用此技巧。Rhino 为错误对象添加了一个非标准属性,您可以访问该属性以打印出有关错误的一些信息。

try {
   someCode()
}
catch(e) { 
     if(e.rhinoException != null) 
     { 
         e.rhinoException.printStackTrace();
     } 
}

您还可以使用 Bindings 来指示出现问题?

我明白你现在在寻找什么。它并不漂亮,实际上它很糟糕,但是你可以访问底层的 JavaScriptException,然后获取你抛出异常的值。

package test;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import sun.org.mozilla.javascript.*;

public class Main {
    private static ScriptEngineManager mgr = new ScriptEngineManager();
    private static ScriptEngine engine = mgr.getEngineByName("JavaScript");

    public static void main(String... args) {
        System.out.println("START");
        try {
            engine.eval("throw { error: \"cheese\", context: \"payload\" };");
        } catch (ScriptException e) {
            JavaScriptException jse = (JavaScriptException)e.getCause();
            Object obj = jse.getValue();
            ScriptableObject so = (ScriptableObject)obj;
            System.out.println(so.get("error", so));
            System.out.println(so.get("context", so));
        }
        System.out.println("END");
    }
}
于 2010-08-14T11:22:32.777 回答
0

您可以将错误对象序列化为 JSON 字符串,然后在 Java 中反序列化。

于 2010-08-14T08:58:35.820 回答
0

FWIW,我认为如果你可以抛出一个 Java 异常对象并将其传播到堆栈中,它也会非常有用。例如,要修改上面的代码:

try {
    engine.eval("throw new java.lang.IllegalArgumentException( 'no cookie!' )" );
} 
catch (ScriptException e) {
    Throwable cause = e.getCause();
    if ( cause != null && cause instanceof IllegalArgumentException ) {
        // ...react explicitly 
    }
    else {
        // ...react generically
    }
于 2010-12-23T17:03:25.437 回答