如何在Rhino中获取当前脚本名称和行号?

4

我正在使用Java和Mozilla Rhino创建游戏引擎,希望所有错误调用一个函数并提供错误消息,如下所示:

...
} catch(Exception e) {
    Abort(e);
}
...
public void Abort(str) {
    System.out.println("Script error in "current_script_name+" line: "+line_number\n\n"+e);
}

对于RhinoException来说这很容易,但是我希望其他的异常,比如IOException也能做到同样的事情。

2个回答

2
这取决于异常被抛出的方式,所以我需要猜测一下。而且它也取决于您使用何种优化级别来执行Rhino。
我猜测异常是从本地Java代码中抛出的(即,您没有使用throw new Packages.java.io.IOException("..."))。在这种情况下,您可以使用printStackTrace()来找出原因。以下是一个小脚本(名为test.jsh.js),您可以在Rhino shell中运行它:
try {
    //  foo does not exist
    var stream = new Packages.java.io.FileInputStream("foo");
} catch (e) {
    e.rhinoException.printStackTrace();
}

以下是命令行和输出结果:

$ java -jar $(cygpath -w /opt/java/rhino/1.7R2/js.jar) -opt -1 test.jsh.js
org.mozilla.javascript.WrappedException: 包装了 java.io.FileNotFoundException: foo (系统找不到指定的文件) (test.jsh.js#4)
        at org.mozilla.javascript.Context.throwAsScriptRuntimeEx(Context.java:1773)
        at org.mozilla.javascript.MemberBox.newInstance(MemberBox.java:202)
        at org.mozilla.javascript.NativeJavaClass.constructSpecific(NativeJavaClass.java:281)
        at org.mozilla.javascript.NativeJavaClass.construct(NativeJavaClass.java:200)
        at org.mozilla.javascript.Interpreter.interpretLoop(Interpreter.java:3377)
        at script(test.jsh.js:4)
        at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:2487)
        at org.mozilla.javascript.InterpretedFunction.call(InterpretedFunction.java:164)
        at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:398)
        at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3065)
        at org.mozilla.javascript.InterpretedFunction.exec(InterpretedFunction.java:175)
        at org.mozilla.javascript.tools.shell.Main.evaluateScript(Main.java:564)
        at org.mozilla.javascript.tools.shell.Main.processFileSecure(Main.java:486)
        at org.mozilla.javascript.tools.shell.Main.processFile(Main.java:452)
        at org.mozilla.javascript.tools.shell.Main.processSource(Main.java:443)
        at org.mozilla.javascript.tools.shell.Main.processFiles(Main.java:196)
        at org.mozilla.javascript.tools.shell.Main$IProxy.run(Main.java:117)
        at org.mozilla.javascript.Context.call(Context.java:515)
        at org.mozilla.javascript.ContextFactory.call(ContextFactory.java:507)
        at org.mozilla.javascript.tools.shell.Main.exec(Main.java:179)
        at org.mozilla.javascript.tools.shell.Main.main(Main.java:157)
Caused by: java.io.FileNotFoundException: foo (系统找不到指定的文件)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.(Unknown Source)
        at java.io.FileInputStream.(Unknown Source)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
        at java.lang.reflect.Constructor.newInstance(Unknown Source)
        at org.mozilla.javascript.MemberBox.newInstance(MemberBox.java:194)
        ... 18 more

如果您确实想要使用上面的Abort()函数,可以从上面的堆栈跟踪中解析出适当的行;或者,您可以显示整个堆栈跟踪,这可能更有帮助,具体取决于您想要做什么。


我有点想这样做,但我想知道是否有更简单/直接的方法。无论如何,谢谢。 - eggbertx

0
为什么不像Log4j一样设置某种日志记录功能来处理异常呢?这样,您可以设置一个properties文件,每次记录时都以相同的方式输出(而不是总是调用Abort()函数)。此外,Log4j支持获取行号和其他功能:Log4j Patterns.

我需要使用一个中止函数,因为我正在重新实现一个游戏引擎,我的目标是让在该游戏引擎中运行的游戏也能在这里运行。 - eggbertx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接