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?
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.
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