elunez/eladmin · error · BadRequestException
请先配置,再操作
Error message
请先配置,再操作
What it means
Thrown by EmailServiceImpl.send(emailVo, emailConfig) when emailConfig.getId() == null — the caller passed a transient EmailConfig, which per find() only happens when no row with id=1 exists in the email config table (find() returns new EmailConfig() via orElseGet). So the admin has never saved SMTP settings; sending is refused before any SMTP connection is attempted.
Source
Thrown at eladmin-tools/src/main/java/me/zhengjie/service/impl/EmailServiceImpl.java:68
if(!emailConfig.getPass().equals(old.getPass())){
// 对称加密
emailConfig.setPass(EncryptUtils.desEncrypt(emailConfig.getPass()));
}
return emailRepository.save(emailConfig);
}
@Override
@Cacheable(key = "'config'")
public EmailConfig find() {
Optional<EmailConfig> emailConfig = emailRepository.findById(1L);
return emailConfig.orElseGet(EmailConfig::new);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void send(EmailVo emailVo, EmailConfig emailConfig){
if(emailConfig.getId() == null){
throw new BadRequestException("请先配置,再操作");
}
// 封装
MailAccount account = new MailAccount();
// 设置用户
String user = emailConfig.getFromUser().split("@")[0];
account.setUser(user);
account.setHost(emailConfig.getHost());
account.setPort(Integer.parseInt(emailConfig.getPort()));
account.setAuth(true);
try {
// 对称解密
account.setPass(EncryptUtils.desDecrypt(emailConfig.getPass()));
} catch (Exception e) {
throw new BadRequestException(e.getMessage());
}
account.setFrom(emailConfig.getUser()+"<"+emailConfig.getFromUser()+">");
// ssl方式发送
account.setSslEnable(true);View on GitHub (pinned to 55fbf70595)
Solutions
- Open the tools -> email config admin page and save host, port, fromUser, password (id becomes 1L).
- Verify row id=1 exists in email_config and that find() now returns it (clear the 'config' cache key if a stale empty object was cached).
- Ensure the config save path uses @CachePut(key='config') (mirroring AliPayServiceImpl) so the empty cached entry is replaced on save.
- Sequence smoke tests: configure email before any test that sends mail.
Example fix
// before
public void send(EmailVo emailVo, EmailConfig emailConfig){
if(emailConfig.getId() == null){
throw new BadRequestException("请先配置,再操作");
}
// after (caller-side, in the verify-code flow):
EmailConfig config = emailService.find();
if(config.getId() == null){
throw new BadRequestException("邮箱服务未配置,请联系管理员先完成邮箱设置");
}
emailService.send(emailService.sendEmail(email, key), config); Defensive patterns
Strategy: validation
Validate before calling
// before any send flow
EmailConfig config = emailService.find();
if (config.getId() == null) {
throw new BadRequestException("邮箱未配置,请先在后台保存邮箱设置");
}
emailService.send(emailVo, config); Try / catch
try { emailService.send(emailVo, config); } catch (BadRequestException e) { if ("请先配置,再操作".equals(e.getMessage())) { /* route to email config page; this is setup, not transient */ } } Prevention
- Include email config in environment provisioning; the feature depends on row id=1 existing.
- Save config through the admin UI (never raw DB inserts) so the password gets encrypted and cache updated.
- Clear the 'config' cache key when fixing config directly in the database.
When it happens
Trigger: Triggering any flow that sends mail (e.g. the verification-code endpoint that calls verifyCode then emailService.send) on a system where the tools email config was never saved; find() is @Cacheable so an empty EmailConfig can also get cached under 'config' after a failed first lookup.
Common situations: Fresh deployment without the email config row; DB migration that dropped email_config; the cached empty config not invalidated after saving real config if save() doesn't @CachePut the same key; testing the 'send code' button before completing setup.
Related errors
AI-assisted analysis of elunez/eladmin@55fbf70595 (2026-08-14).
Data as JSON: /api/errors/7e56d30b34304a48.
Report an issue: GitHub.