我可以在eval的Groovy脚本中获取错误的行号吗?

时间:2013-01-21 18:26:35

标签: groovy

我有一段代码用于运行用户提供的Groovy脚本,如下所示:

def scriptText = <something user entered>
def manager = new ScriptEngineManager()
def engine = manager.getEngineByName('Groovy')

try {
    engine.eval(scriptText)
}
catch (ScriptException e) {
    println 'Script error at line ' + e.getLineNumber() + ', column ' + e.getColumnNumber() + ': ' + e.getMessage()
}

如果我故意在提供的输入脚本中输入错误,则此代码将打印以下内容(包含未定义的行号和列号):

Script error at line -1, column -1: javax.script.ScriptException: groovy.lang.MissingPropertyException: No such property: blah for class: Script1

我也尝试过调用Eval.me(scriptText),因为调用代码也是Groovy,但后来我得到了一个大堆栈跟踪,其中包含了脚本错误的原因,如下所示:

Exception in thread "main" groovy.lang.MissingPropertyException: No such property: blah for class: Script1
Possible solutions: class
    at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:50)
    at org.codehaus.groovy.runtime.callsite.PogoGetPropertySite.getProperty(PogoGetPropertySite.java:49)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:231)
    at Script1.run(Script1.groovy:6)  <---- this is the script error
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:518)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:556)
    at groovy.lang.GroovyShell.evaluate(GroovyShell.java:527)
    at groovy.util.Eval.me(Eval.java:68)
    at groovy.util.Eval.me(Eval.java:51)
    at groovy.util.Eval$me.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
    at com.kminnovations.metrics.engine.tester.Testing.parseFile(Testing.groovy:32)
    at com.kminnovations.metrics.engine.tester.Testing$parseFile.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120)
    at com.kminnovations.metrics.engine.tester.MetricsEngineTester.main(MetricsEngineTester.groovy:23)

有没有办法从程序中执行脚本文本并准确获取脚本中错误的位置,以便我可以为提供它的用户清楚地显示它?

1 个答案:

答案 0 :(得分:1)

我认为您仍然可以通过导航到根本原因并搜索ScriptN.groovy等源代码来获取该行,因为ScriptEngineManager将为每个已执行的脚本自动生成此名称。

def manager = new ScriptEngineManager()
def engine = manager.getEngineByName('Groovy')

try {
    engine.eval(scriptText)
} catch (javax.script.ScriptException e) {
    def cause = rootCause(e)
    def line = cause.stackTrace.find { 
        it.fileName ==~ /^Script\d+\.groovy$/ 
    }.lineNumber
    println "Line $line: $cause.message"
}

def rootCause(Exception e) {
    Throwable t = e;
    while (t.cause != null) t = t.cause;
    t
}

您可能希望在apache.commons.ExceptionUtils中有更复杂的rootCause