Как мога да получа текущото име на скрипт и номер на ред в Rhino?

Създавам двигател за игри, използвайки 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.


person eggbertx    schedule 18.08.2011    source източник


Отговори (2)


Зависи малко как се хвърлят изключенията, така че ще трябва да направя предположение. И зависи от нивото на оптимизация, което използвате, за да изпълните Rhino.

Предполагам, че изключенията се изхвърлят от родния Java код (т.е. не използвате throw new Packages.java.io.IOException("...")). В такъв случай можете да използвате printStackTrace(), за да го разберете. Ето малък скрипт (с име test.jsh.js, който ще видите в проследяването на стека), който можете да стартирате в обвивката на Rhino:

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: Wrapped java.io.FileNotFoundException: foo (The system cannot find the file specified) (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 (The system cannot find the file specified)
        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(), която имате по-горе, можете да анализирате съответния ред от проследяването на стека по-горе; като алтернатива можете да покажете цялото проследяване на стека, което може да бъде по-полезно, в зависимост от това какво искате да направите.

person David P. Caldwell    schedule 25.08.2011
comment
Някак си мислех да го направя, но исках да знам дали има по-лесен/по-прост начин. Благодаря на всеки - person eggbertx; 05.09.2011

Защо не настроите някаква функция за регистриране за вашите изключения като Log4j? С това можете да зададете properties файл, така че всеки път, когато регистрирате нещо, той извежда по същия начин (вместо винаги да извиква Abort() функция. Освен това Log4j поддържа получаване на номера на редове и други функции: Log4j Patterns.

person Dan W    schedule 25.08.2011
comment
Трябва да използвам функция за прекъсване, защото внедрявам отново двигател на играта и целта ми е игрите, които се изпълняват в този двигател на играта, да работят и в това. - person eggbertx; 05.09.2011