Skip to content

feat(template-st): log StringTemplate compile/runtime errors via SLF4J #3708

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

renechoi
Copy link

@renechoi renechoi commented Jun 29, 2025

Why

StringTemplate v4 defaults to ErrorManager.DEFAULT_ERROR_LISTENER, which
writes compile-time and runtime diagnostics directly to stderr. In most
Spring-based deployments the process stderr stream is either discarded or
treated as an unstructured blob that never reaches Logstash/Grafana, making
template failures virtually invisible at run-time.

Issue #3604 “PromptTemplate should configure error reporting in String
Template”
highlighted this gap and requested a way to surface those
messages through the conventional SLF4J pipeline. This commit fulfils that
request and aligns error handling with the rest of the framework logging
strategy.

What

  • Slf4jStErrorListener – new STErrorListener implementation that
    delegates compileTimeError, runTimeError, IOError, and
    internalError events to the Logger of StTemplateRenderer.
  • StTemplateRenderer
    • Allocates a single STGroup per render operation and registers the
      SLF4J listener so every template instance receives structured logging.
    • Keeps constructor/builder API unchanged; no public surface breakage.
  • Unit tests
    • Added malformedTemplateShouldLogErrorViaSlf4j which
      • Injects a Logback ListAppender to capture log events.
      • Verifies that a malformed template triggers an ERROR log entry and
        that nothing is emitted to stderr.
    • Existing tests updated to work with the new code path but remain
      behaviour-identical.
  • Docs / Javadoc
    • Updated class‐level Javadoc in StTemplateRenderer to mention the new
      error-reporting mechanism.

How

When createST(String template) is invoked, the renderer now:

  1. Creates an STGroup with the configured delimiters.
  2. Registers the shared Slf4jStErrorListener instance on the group.
  3. Instantiates the ST template from that group.

Because the listener is stateless and threads only interact with it via the
SLF4J facade, the change is thread-safe and produces no additional
allocation hot-spots beyond the lifetime of the template rendering call.

Impact

  • Operational visibility – Template compile/runtime errors now appear in
    application logs with timestamps, context, and stack traces, making them
    searchable and monitorable.
  • No breaking changes – The public API, default delimiters, and
    validation semantics remain untouched. Projects depending on
    StTemplateRenderer require no code changes.
  • Minimal footprint – Adds ~90 logical lines, zero external
    dependencies.

Migration Notes

No migration steps are required. Applications will automatically benefit
from structured error logging after updating to the version that includes
this commit.

References

Signed-off-by: [email protected]

Fixes spring-projectsGH-3604 (spring-projects#3604)

### Why
StringTemplate’s default ErrorManager writes diagnostics to stderr, which
is invisible in most Spring deployments. This change redirects those
messages to SLF4J so they reach Logstash / CloudWatch / etc.

### What
* Add `Slf4jStErrorListener` (STErrorListener -> SLF4J).
* Create STGroup with listener inside `StTemplateRenderer#createST`.
* JUnit `malformedTemplateShouldLogErrorViaSlf4j`.
* Javadoc updates.

### Impact
No API changes; applications automatically get structured error logs.

Signed-off-by: Your Name <[email protected]>
Signed-off-by: renechoi <[email protected]>
@renechoi renechoi force-pushed the GH-3604-slf4j-error-listener branch from 0f55d4d to 31db4d2 Compare June 29, 2025 04:01
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please reorganize the imports in the following order:

  1. java.*
  2. other imports
  3. org.springframework.*
  4. static imports

Also, please avoid using wildcard imports .*


For reference, you can refer to the example in this file:
OpenAiApiIT.java.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, unnecessary tabs have been added. It would be great if you could remove those as well.

}
catch (Exception ex) {
throw new IllegalArgumentException("The template string is not valid.", ex);
}
}


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line appears to have an unnecessary line break.

@sunyuhan1998
Copy link
Contributor

sunyuhan1998 commented Jun 29, 2025

Hi @renechoi , thank you for your contribution! I think this is a duplicate PR, as the issue is already being addressed through PR #3606 , which is currently under the 1.1.x milestone. I noticed that your PR includes unit tests for the log output, and I think this is a great addition!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants