If subject or message is empty in email confirmation template, responses are silently discarded
GENERAL
TESTING
GENERAL
TESTING
Description
If an email confirmation template is edited and the subject is empty, then user responses to an evaluation get silently discarded.
The underlying cause is this exception from TextTemplateLogicUtils.java
2015-04-21 16:09:42,586 DEBUG ajp-bio-8009-exec-3 org.sakaiproject.evaluation.logic.EvalDeliveryServiceImpl - Unable to send the confirmation email to user: f5376d78-d3ad-45e4-007d-cd6dc37c1966 java.lang.IllegalArgumentException: The textTemplate cannot be null or empty string, please pass in at least something in the template or do not call this method at org.sakaiproject.evaluation.utils.TextTemplateLogicUtils.processTextTemplate(TextTemplateLogicUtils.java:91) at org.sakaiproject.evaluation.logic.EvalEmailsLogicImpl.makeEmailMessage(EvalEmailsLogicImpl.java:864) at org.sakaiproject.evaluation.logic.EvalEmailsLogicImpl.makeEmailMessage(EvalEmailsLogicImpl.java:721) at org.sakaiproject.evaluation.logic.EvalEmailsLogicImpl.sendEvalSubmissionConfirmationEmail(EvalEmailsLogicImpl.java:1268) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at com.sun.proxy.$Proxy60.sendEvalSubmissionConfirmationEmail(Unknown Source) at org.sakaiproject.evaluation.logic.EvalDeliveryServiceImpl.saveResponse(EvalDeliveryServiceImpl.java:212) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at com.sun.proxy.$Proxy88.saveResponse(Unknown Source) at org.sakaiproject.evaluation.tool.LocalResponsesLogic.saveResponse(LocalResponsesLogic.java:117) at org.sakaiproject.evaluation.tool.locators.ResponseBeanLocator.saveAll(ResponseBeanLocator.java:98) at org.sakaiproject.evaluation.tool.locators.ResponseBeanLocator.saveAll(ResponseBeanLocator.java:67) at org.sakaiproject.evaluation.tool.TakeEvalBean.submitEvaluation(TakeEvalBean.java:107) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606)
This seems to cause the transaction which includes saving the response set to get rolled back so you get a log line like this:
but not an ideal fix for general use, because it uses a default string hard-coded to English. Really should get handled when a submission confirmation template is saved.
Also an exception sending an email confirmation should not prevent the response set from being saved, but the transaction handling there is beyond me.
If an email confirmation template is edited and the subject is empty, then user responses to an evaluation get silently discarded.
The underlying cause is this exception from TextTemplateLogicUtils.java
2015-04-21 16:09:42,586 DEBUG ajp-bio-8009-exec-3
org.sakaiproject.evaluation.logic.EvalDeliveryServiceImpl - Unable to send the confirmation email to user: f5376d78-d3ad-45e4-007d-cd6dc37c1966
java.lang.IllegalArgumentException: The textTemplate cannot be null or empty string, please pass in at least something in the template or do not call this method
at org.sakaiproject.evaluation.utils.TextTemplateLogicUtils.processTextTemplate(TextTemplateLogicUtils.java:91)
at org.sakaiproject.evaluation.logic.EvalEmailsLogicImpl.makeEmailMessage(EvalEmailsLogicImpl.java:864)
at org.sakaiproject.evaluation.logic.EvalEmailsLogicImpl.makeEmailMessage(EvalEmailsLogicImpl.java:721)
at org.sakaiproject.evaluation.logic.EvalEmailsLogicImpl.sendEvalSubmissionConfirmationEmail(EvalEmailsLogicImpl.java:1268)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy60.sendEvalSubmissionConfirmationEmail(Unknown Source)
at org.sakaiproject.evaluation.logic.EvalDeliveryServiceImpl.saveResponse(EvalDeliveryServiceImpl.java:212)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at com.sun.proxy.$Proxy88.saveResponse(Unknown Source)
at org.sakaiproject.evaluation.tool.LocalResponsesLogic.saveResponse(LocalResponsesLogic.java:117)
at org.sakaiproject.evaluation.tool.locators.ResponseBeanLocator.saveAll(ResponseBeanLocator.java:98)
at org.sakaiproject.evaluation.tool.locators.ResponseBeanLocator.saveAll(ResponseBeanLocator.java:67)
at org.sakaiproject.evaluation.tool.TakeEvalBean.submitEvaluation(TakeEvalBean.java:107)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
This seems to cause the transaction which includes saving the response set to get rolled back so you get a log line like this:
2015-04-21 15:37:13,716 INFO ajp-bio-8009-exec-12 org.sakaiproject.evaluation.tool.wrapper.ModelAccessWrapperInvoker - Eval: Caught transaction rollback exception: null