Skip to content

Commit 940bcf3

Browse files
sunyuhan1998ericbottard
authored andcommitted
Add STErrorListener to SLF4J bridge.
`StTemplateRenderer` uses `StringTemplate` as the template rendering engine. By default, StringTemplate use `org.stringtemplate.v4.misc.ErrorManager#DEFAULT_ERROR_LISTENER` as the error listener for rendering exceptions, which outputs errors via System.err.println. This may cause users to miss important information about rendering errors. This commit introduces a custom `STErrorListener` that logs exceptions to the application's logging system instead. Signed-off-by: Sun Yuhan <sunyuhan1998@users.noreply.github.com> Signed-off-by: Eric Bottard <eric.bottard@broadcom.com> Fixes #3604
1 parent aeb9f8a commit 940bcf3

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2023-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.template.st;
18+
19+
import org.slf4j.Logger;
20+
import org.stringtemplate.v4.STErrorListener;
21+
import org.stringtemplate.v4.misc.ErrorType;
22+
import org.stringtemplate.v4.misc.STMessage;
23+
24+
/**
25+
* An {@link STErrorListener} that delegates to {@link Logger slf4j}.
26+
*
27+
* @author Sun Yuhan
28+
*/
29+
public class Slf4jStErrorListener implements STErrorListener {
30+
31+
private final Logger logger;
32+
33+
/* package */ Slf4jStErrorListener(Logger logger) {
34+
this.logger = logger;
35+
}
36+
37+
@Override
38+
public void compileTimeError(STMessage msg) {
39+
logger.error(msg.toString());
40+
}
41+
42+
@Override
43+
public void runTimeError(STMessage msg) {
44+
if (msg.error != ErrorType.NO_SUCH_PROPERTY) { // ignore these
45+
logger.error(msg.toString());
46+
}
47+
else {
48+
logger.warn(msg.toString());
49+
}
50+
}
51+
52+
@Override
53+
public void IOError(STMessage msg) {
54+
logger.error(msg.toString());
55+
}
56+
57+
@Override
58+
public void internalError(STMessage msg) {
59+
logger.error(msg.toString());
60+
}
61+
62+
}

spring-ai-template-st/src/main/java/org/springframework/ai/template/st/StTemplateRenderer.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.slf4j.Logger;
2626
import org.slf4j.LoggerFactory;
2727
import org.stringtemplate.v4.ST;
28+
import org.stringtemplate.v4.STGroup;
2829
import org.stringtemplate.v4.compiler.Compiler;
2930
import org.stringtemplate.v4.compiler.STLexer;
3031

@@ -113,7 +114,9 @@ public String apply(String template, Map<String, Object> variables) {
113114

114115
private ST createST(String template) {
115116
try {
116-
return new ST(template, this.startDelimiterToken, this.endDelimiterToken);
117+
STGroup group = new STGroup(this.startDelimiterToken, this.endDelimiterToken);
118+
group.setListener(new Slf4jStErrorListener(logger));
119+
return new ST(group, template);
117120
}
118121
catch (Exception ex) {
119122
throw new IllegalArgumentException("The template string is not valid.", ex);

0 commit comments

Comments
 (0)