2

我无法捕捉到 STGroupFile 抛出的 STException。这是个问题。如果模板不好,我需要中止。为了重现这个问题,我有一个名为 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);

但我无法捕捉到这个异常。我怎样才能捕捉到这个异常并中止?

4

2 回答 2

3

按照 ANTLR Guy 的建议,我扩展了 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()

当它执行时,有一个讨厌的副作用,即堆栈跟踪被打印两次,但程序在打印最后一句“你不应该看到这一行”之前中止,这是所需的行为。

于 2014-05-07T01:17:45.787 回答
0

正如您在另一封电子邮件中指出的那样:“我发现异常实际上被捕获而不是重新抛出。这发生在 STGroup.java 中:”

catch (Exception e) { errMgr.IOError(null, ErrorType.CANT_LOAD_GROUP_FILE, e, fileName); }

为什么不重写 IOError 函数(或它调用的侦听器中的函数?)以重新抛出 e?

于 2014-05-06T17:27:45.750 回答