paascloud/paascloud-master · error · OpcBizException
OPC10040006
OPC10040006
Error message
OPC10040006
What it means
OPC10040006 ("获取模板信息失败") is thrown by OptSendMailServiceImpl.sendTemplateMail when the Velocity template rendering (optVelocityService.getTemplate) fails with IOException or TemplateException. IOException usually means the template resource cannot be found/read; TemplateException means the template parsed/rendered badly (bad syntax, missing variable directives). The exception wraps the cause and the mail is never sent.
Solutions
- Verify templateLocation resolves on the classpath (e.g. starts with a correct classpath prefix and the file exists in the built artifact).
- Check the wrapped IOException/TemplateException in the log — TemplateException gives line/column of the syntax error.
- Fix Velocity template syntax errors (#if/#foreach directives, $variable references) reported in the cause.
- Ensure the model map contains every variable the template references.
- Add a startup check/test that renders each registered template to catch missing templates at deploy time.
Example fix
// before: template path typo fails at runtime
mailService.sendTemplateMail(model, "/templates/mail/notif.vm", subject, to);
// after: fail fast if template missing
classPathResource "/templates/mail/notify.vm";
try (InputStream in = getClass().getResourceAsStream(templateLocation)) {
if (in == null) { throw new IllegalStateException("template missing: " + templateLocation); }
}
mailService.sendTemplateMail(model, "/templates/mail/notify.vm", subject, to); Defensive patterns
Strategy: validation
Validate before calling
try (InputStream in = getClass().getResourceAsStream(templateLocation)) {
if (in == null) {
throw new IllegalStateException("Mail template not on classpath: " + templateLocation);
}
} Type guard
boolean templateExists(String location) {
return getClass().getResource(location) != null;
} Try / catch
try {
mailService.sendTemplateMail(model, templateLocation, subject, to);
} catch (OpcBizException e) {
if (e.getCode() == 10040006) {
log.error("Mail template render failed for {}", templateLocation, e.getCause());
}
throw e;
} Prevention
- Keep templates inside src/main/resources and verify they land in the jar.
- Add a unit test that renders every template with a full model.
- Fix Velocity syntax errors immediately when editing templates.
- Version-control template changes together with model changes.
- Use constants for template locations instead of inline strings.
When it happens
Trigger: Calling sendTemplateMail(model, templateLocation, subject, to) where templateLocation does not resolve to an existing template resource, or the .vm template has Velocity syntax errors, or the model lacks variables the template requires.
Common situations: Renaming/moving template files without updating templateLocation; packaging templates outside the jar so classpath loading fails; Velocity directive typos after editing; template referencing a model key removed in a new release.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
AI-assisted analysis of paascloud/paascloud-master@781281a950 (2026-09-10).
Data as JSON: /api/errors/bee7cf21921981ad.
Report an issue: GitHub.
Appendix: source
Thrown at paascloud-provider/paascloud-provider-opc/src/main/java/com/paascloud/provider/service/impl/OptSendMailServiceImpl.java:116
helper.setSubject(subject);
helper.setText(text, true);
} catch (MessagingException e) {
log.error("生成邮件消息体, 出现异常={}", e.getMessage(), e);
throw new OpcBizException(ErrorCodeEnum.OPC10040005);
}
return mimeMessage;
}
@Override
public int sendTemplateMail(Map<String, Object> model, String templateLocation, String subject, Set<String> to) {
log.info("sendTemplateMail - 发送模板邮件. subject={}, model={}, to={}, templateLocation={}", subject, model, to, templateLocation);
String text;
try {
text = optVelocityService.getTemplate(model, templateLocation);
} catch (IOException | TemplateException e) {
log.info("sendTemplateMail [FAIL] ex={}", e.getMessage(), e);
throw new OpcBizException(ErrorCodeEnum.OPC10040006, e);
}
return this.sendTemplateMail(subject, text, to);
}
private String[] setToArray(Set<String> to) {
Preconditions.checkArgument(PublicUtil.isNotEmpty(to), "请输入收件人邮箱");
Set<String> toSet = Sets.newHashSet();
for (String toStr : to) {
toStr = toStr.trim();
if (PubUtils.isEmail(toStr)) {
toSet.add(toStr);
}
}
if (PublicUtil.isEmpty(toSet)) {
return null;
}View on GitHub (pinned to 781281a950)