我有一段代码用于运行用户提供的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)
有没有办法从程序中执行脚本文本并准确获取脚本中错误的位置,以便我可以为提供它的用户清楚地显示它?
答案 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