如何优雅收集javax.mail多个set方法的异常并统一抛出?
解决Javax.Mail构建Message时收集所有异常的简洁方案
你可以通过封装通用的异常收集工具方法来避免重复写try-catch,同时收集所有set操作抛出的异常,最后统一包装成IllegalArgumentException抛出。以下是几种实用的实现方式:
方式一:通用Runnable执行器(基础版)
先写一个工具方法,批量执行传入的操作并收集异常:
private List<Exception> collectExceptions(Runnable... operations) { List<Exception> exceptions = new ArrayList<>(); for (Runnable op : operations) { try { op.run(); } catch (Exception e) { exceptions.add(e); } } return exceptions; }
然后在构建Message时,把每个set操作以lambda形式传入:
public void buildMailMessage(Message message, String content, Address[] recipients) { // 批量执行所有set操作,收集异常 List<Exception> exceptions = collectExceptions( () -> message.setContent(content, "text/html; charset=utf-8"), () -> message.setRecipients(Message.RecipientType.TO, recipients), () -> message.setSubject("测试邮件"), () -> message.setSentDate(new Date()) ); // 有异常则统一包装抛出 if (!exceptions.isEmpty()) { IllegalArgumentException iae = new IllegalArgumentException("构建邮件Message时存在参数错误"); exceptions.forEach(iae::addSuppressed); throw iae; } }
这种方式的核心是把每个set操作抽象成Runnable,让工具方法统一处理异常捕获,避免重复写try-catch代码。
方式二:针对Message的专用执行器(更贴合场景)
如果想让代码更清晰,可以把工具方法改成针对Message的操作,用Consumer<Message>来封装每个set逻辑:
private List<Exception> collectMessageExceptions(Message message, Consumer<Message>... operations) { List<Exception> exceptions = new ArrayList<>(); for (Consumer<Message> op : operations) { try { op.accept(message); } catch (RuntimeException | MessagingException e) { // 只捕获Javax.Mail相关异常和运行时异常,避免捕获所有Exception exceptions.add(e); } } return exceptions; }
调用时直接传入针对Message的操作:
List<Exception> exceptions = collectMessageExceptions(message, msg -> msg.setContent(content, "text/html; charset=utf-8"), msg -> msg.setRecipients(Message.RecipientType.TO, recipients), msg -> msg.setSubject("测试邮件") );
方式三:带错误描述的异常收集(更友好的错误提示)
如果希望抛出的异常能直接显示每个操作的错误信息,不用依赖抑制异常,可以调整工具方法收集错误描述:
private List<String> collectMessageErrors(Message message, Pair<String, Consumer<Message>>... operations) { List<String> errors = new ArrayList<>(); for (Pair<String, Consumer<Message>> op : operations) { try { op.getValue().accept(message); } catch (RuntimeException | MessagingException e) { errors.add(op.getKey() + "失败: " + e.getMessage()); } } return errors; }
调用时给每个操作加上描述:
List<String> errors = collectMessageErrors(message, Pair.of("设置邮件内容", msg -> msg.setContent(content, "text/html; charset=utf-8")), Pair.of("设置收件人列表", msg -> msg.setRecipients(Message.RecipientType.TO, recipients)), Pair.of("设置邮件主题", msg -> msg.setSubject("测试邮件")) ); if (!errors.isEmpty()) { throw new IllegalArgumentException("构建邮件Message失败: " + String.join("; ", errors)); }
这种方式抛出的异常信息更直观,调用者不用再去解析抑制异常,直接就能看到所有错误点。
内容的提问来源于stack exchange,提问作者EarthTurtle
相关产品推荐
相关产品推荐

