Unable to catch STException in StringTemplate 4

旧城冷巷雨未停 提交于 2019-12-13 12:17:54

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!