Невозможно отловить STException в StringTemplate 4
Я не могу поймать STException, выданный STGroupFile. Это проблема. Мне нужно прервать, если шаблон плохой. Чтобы воспроизвести эту проблему, у меня есть этот неправильный файл шаблона с именем tmp.stg:
temp1(param1)::=<<
%if(param1)%
%param1:{%temp2(p)%}; separator"\n"%
%endif%
>>
И этот отличный код для его обработки:
#!/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()
Когда я запускаю этот скрипт, я получаю сообщение об ошибке, но не могу поймать исключение:
can't load group file file:tmp.stg
Сообщение об ошибке приходит из STGroupFile.java:
throw new STException("can't load group file "+fileName, e);
Но я не могу поймать это исключение. Как я могу поймать это исключение и отменить?
2 ответа
Следуя совету парня ANTLR, я расширил STErrorListener для выдачи исключения вместо печати сообщения в stderr. Это выглядит так:
Файл: 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());
}
}
}
Затем мастер сценарий bin/gex.groovy
выглядит так:
#!/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()
Когда он выполняется, возникает неприятный побочный эффект, когда трассировка стека печатается дважды, но программа прерывает работу перед выводом последнего предложения "Вы не должны видеть эту строку", что является желаемым поведением.
Как вы указали в отдельном электронном письме: "Я обнаружил, что исключение фактически перехватывается и не перебрасывается. Это происходит внутри STGroup.java:"
catch (Exception e) {
errMgr.IOError(null, ErrorType.CANT_LOAD_GROUP_FILE, e, fileName);
}
Почему бы не переопределить функцию IOError (или функцию в слушателе, которую она вызывает?), Чтобы просто перебросить e?