问题
I am unable to catch the STException thrown by the STGroupFile. This is a problem. I need to abort if the template is bad. To reproduce this problem, I have this incorrect template file called tmp.stg:
temp1(param1)::=<<
%if(param1)%
%param1:{%temp2(p)%}; separator"\n"%
%endif%
>>
And this groovy code to process it:
#!/usr/bin/env groovy
@Grab(group="org.antlr", module="ST4", version="4.0.8")
import org.stringtemplate.v4.STGroupFile;
import org.stringtemplate.v4.NumberRenderer;
public class Gex {
public static void main(String [] args) {
System.out.println("Processing...")
File fn = new File("tmp.stg")
STGroupFile group;
try {
group = new STGroupFile(fn.toString());
} catch (Throwable e) {
throw new Exception("Caught first exception");
}
try {
group.registerRenderer(Integer.class, new NumberRenderer());
} catch (Throwable e) {
throw new Exception("Caught second exception");
}
throw new Exception("You should not see this");
}
}
Gex.main()
When I run that script, I get an error message but I cannot catch the exception:
can't load group file file:tmp.stg
The error message comes from STGroupFile.java:
throw new STException("can't load group file "+fileName, e);
But I am unable to catch this exception. How can I catch this exception and abort?
回答1:
Following the advice of The ANTLR Guy, I extended the STErrorListener to throw an exception instead of printing a message to stderr. It looks like this:
File: lib/GexListener.groovy
import org.stringtemplate.v4.STErrorListener;
import org.stringtemplate.v4.misc.STMessage;
import org.stringtemplate.v4.misc.ErrorType;
class GexListener implements STErrorListener {
@Override
public void compileTimeError(STMessage msg) {
throw new Exception(msg.toString());
}
@Override
public void runTimeError(STMessage msg) {
if ( msg.error != ErrorType.NO_SUCH_PROPERTY ) { // ignore these
throw new Exception(msg.toString());
}
}
@Override
public void IOError(STMessage msg) {
throw new Exception(msg.toString());
}
@Override
public void internalError(STMessage msg) {
throw new Exception(msg.toString());
}
public void error(String s) { error(s, null); }
public void error(String s, Throwable e) {
System.err.println(s);
if ( e!=null ) {
throw new Exception(msg.toString());
}
}
}
Then the master script bin/gex.groovy
looks like this:
#!/bin/bash
//usr/bin/env groovy -cp ${0%/*}/../lib "$0" "$@"; exit $?
@Grab(group="org.antlr", module="ST4", version="4.0.8")
import org.stringtemplate.v4.STGroupFile;
import org.stringtemplate.v4.NumberRenderer;
import GexListener
public class Gex {
public static void main(String [] args) {
System.out.println("Processing...")
File fn = new File("tmp.stg")
STGroupFile group;
GexListener listener = new GexListener();
group = new STGroupFile(fn.toString());
group.setListener(listener);
group.registerRenderer(Integer.class, new NumberRenderer());
System.out.println("You should not see this line")
}
}
Gex.main()
When it executes, there is a nasty side effect where the stacktrace is printed twice, but the program aborts before printing the last sentence "You should not see this line", which is the desired behaviour.
回答2:
As you pointed out in a separate email: "I discovered that the exception is actually caught and not re-thrown. This happens inside STGroup.java:"
catch (Exception e) {
errMgr.IOError(null, ErrorType.CANT_LOAD_GROUP_FILE, e, fileName);
}
Why not override the IOError function (or a function in the listener that it calls?) to just re-throw e?
来源:https://stackoverflow.com/questions/23484213/unable-to-catch-stexception-in-stringtemplate-4