Using Spring 3.0, I wrote an interface to hide the template engine that I used to send mail from the application. Interface
public interface MailSender { public void send(String[] to, String from, String subject, String template, Map<Object, Object> model, boolean isHtml, Map<String, Resource> attachments, Map<String, Resource> inline) throws MailException; }
Then the Velocity implementation
public class MailSenderVelocity implements MailSender { private JavaMailSender sender; private VelocityEngine engine; @Override public void send(final String[] to, final String from, final String subject, final String template, final Map<Object, Object> model, final boolean isHtml, final Map<String, Resource> attachments, final Map<String, Resource> inline) throws com.engrid.mail.MailException { try {
As a good programmer, I wrote test cases for different scenarios so that everything would work correctly. One of my cases is when the attachment is specified, but the file itself does not exist, in particular
@Test(expected=MailException.class) public void testSend_MissingAttachment() throws IOException, MailException { // create new object MailSenderVelocity testSender = new MailSenderVelocity(); testSender.setEngine(engine); testSender.setSender(sender); // assign properties String subject = "testSend_MissingAttachment"; String template = "simple.vm"; Map<Object, Object> model = new HashMap<Object, Object>(); model.put("user", "User"); boolean isHtml = true; Map<String, Resource> attachments = new HashMap<String, Resource>(); String file = "notext.txt"; attachments.put(file, templateDirectory.createRelative(file)); Map<String, Resource> inline = null; // send a message -- will fail because it won't find the file to attach testSender.send(this.to, this.from, subject, template, model, isHtml, attachments, inline); }
Now the test result throws the expected exception
org.springframework.mail.MailSendException: Failed messages: javax.mail.MessagingException: IOException while sending message; nested exception is: java.io.FileNotFoundException: class path resource [com/company/mail/template/notext.txt] cannot be opened because it does not exist; message exception details (1) are: Failed message 1: javax.mail.MessagingException: IOException while sending message; nested exception is: java.io.FileNotFoundException: class path resource [com/company/mail/template/notext.txt] cannot be opened because it does not exist at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:625) at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:416) at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:340) at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:355) at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:344) at com.company.mail.MailSenderVelocity.send(MailSenderVelocity.java:103) at com.company.mail.MailSenderVelocity.send(MailSenderVelocity.java:53) at com.company.mail.MailSenderVelocityTest.testSend_MissingAttachment(MailSenderVelocityTest.java:136) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37) at java.lang.reflect.Method.invoke(Method.java:600) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:22) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:46) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41) at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:220) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:45) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196) Caused by: java.io.FileNotFoundException: class path resource [com/company/mail/template/notext.txt] cannot be opened because it does not exist at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:158) at org.springframework.mail.javamail.MimeMessageHelper$1.getInputStream(MimeMessageHelper.java:1086) at javax.activation.DataHandler.writeTo(DataHandler.java:302) at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1350) at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:845) at javax.mail.internet.MimeMultipart.writeTo(MimeMultipart.java:361) at com.sun.mail.handlers.multipart_mixed.writeTo(multipart_mixed.java:85) at javax.activation.ObjectDataContentHandler.writeTo(DataHandler.java:881) at javax.activation.DataHandler.writeTo(DataHandler.java:314) at javax.mail.internet.MimeBodyPart.writeTo(MimeBodyPart.java:1350) at javax.mail.internet.MimeMessage.writeTo(MimeMessage.java:1683) at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:585) ... 38 more 2010-11-11 13:50:30,261
However, the e-mail message is still sent to the specified recipient from the specified sender. All other things (theme, body, etc.) are empty. How to stop sending email when an exception is thrown while creating an email.