In this example I made a custom exception page where the stacktrace is displayed in an textarea and added a email action so the error can be send to support.
This is how you can add a exception page to the taskflow. First create a view in the taskflow and generate a page on this view. Select the view and press the mark Exception Handler button.
This is how it looks in the taskflow. You don't have to create a control flow rules because you can have only one exception view and every not handled error is redirected to this view
Here you see that a normal error like a duplicate key is still displayed at the right place
My jsf exception page looks like this.
<af:panelFormLayout>
<af:outputText value="Exception Occured"
inlineStyle="color:Red; font-size:large;"/>
<af:commandButton text="Send exception to support"
action="#{exception.sendMail}"/>
<af:inputText label="Message"
value="#{controllerContext.currentViewPort.exceptionData.message}"
rendered="#{controllerContext.currentViewPort.exceptionPresent}"
/>
<af:inputText label="Stacktrace"
value="#{exception.stacktrace}" rows="20"
readOnly="true"
rendered="#{controllerContext.currentViewPort.exceptionPresent}"
columns="100"/>
</af:panelFormLayout>
Here is the code of the backing bean which retrieves the stacktrace of the error and send the error to support.
package nl.ordina.bean;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import oracle.adf.controller.ControllerContext;
public class Exception {
private ControllerContext cc;
public Exception() {
cc = ControllerContext.getInstance();
}
public String getStacktrace() {
if ( cc.getCurrentViewPort().getExceptionData()!=null ) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
cc.getCurrentViewPort().getExceptionData().printStackTrace(pw);
return sw.toString();
}
return null;
}
public String sendMail()
{
Properties p = System.getProperties();
p.put("mail.transport.protocol","smtp");
p.put("mail.smtp.host","smtp.xs4all.nl");
Session session = Session.getInstance(p);
MimeMessage message = new MimeMessage(session);
try {
message.setFrom(new InternetAddress("xxxx@xxxx.nl"));
message.addRecipient(Message.RecipientType.TO,new InternetAddress("xxxx@xxxxx.nl"));
message.setSubject(cc.getCurrentViewPort().getExceptionData().getMessage());
message.setContent(getStacktrace(),"text/plain");
Transport.send(message);
} catch (MessagingException e) {
// TODO
e.printStackTrace();
}
System.out.println(message.toString());
return null;
}
}
Hi Edwin,
ReplyDeleteA wonderful post.Very much similar to what I am looking for.Can you please post the sample application so that I could understand in more detail?
Thanks,
Prasanna
Hi Edwin,
ReplyDeleteAs you have used jsf page for the exception page, I am using a pagefragment and in that case the page is not being called.It there another approach to do it for fragments.I tried calling the exception page from adfc.config but when I do so, once the page is called I am not beinh able to navigate to other links/regions..Could you please help me out in this?
Thanks,
Prasanna
Could you please post the sample application. Thank you...
ReplyDelete