1) Binding Layer : At binding layer, the exceptions can be either be handled for all the pages included in dataBinding.cpx file or for an individual page.
Handle exception of all the pages:
To handle binding layer exception for all the pages, extend the DCErrorHandlerImpl class and override the reportException method. Register this custom error handler class in DataBinding.cpx file under Application tag as follows:
ErrorHandlerClass="com.exception.handler.CustomErrorHandler "
public class CustomErrorHandler extends DCErrorHandlerImpl {
private String[][] overrideExceptions = {{"oracle.jbo.JboException", "CUST_001","This is custom JBO exception message."}};
public CustomErrorHandler (boolean setToThrow) {
super(setToThrow);
}
public CustomErrorHandler () {
this(true);
}
@Override
public void reportException(DCBindingContainer bc, Exception ex) {
BindingContext ctx = bc.getBindingContext();
String err_code = null;
if (ex instanceof TxnValException) {
// Handle JBO-27023
// Display exception message
}
if (ex instanceof oracle.jbo.DMLException) {
// Handle JBO-26061
// Display exception message } else if (ex instanceof oracle.jbo.JboException) {
// Display exception message
} else {
super.reportException(bc, ex);
}
}
@Override
protected boolean skipException(Exception ex) {
// Override this method to skip any exception.
return super.skipException(ex);
}
@Override
public String getDisplayMessage(BindingContext context,
Exception exception) {
//Override this method to return custom error message
return message;
}
}
Handle exception of individual page:
To handle exception for a single page, create a CustomFacesPageLifeCycle class that extends FacesPageLifecycle. Now override the reportErrors method:
public void reportErrors(PageLifecycleContext pageLifecycleContext) {
DCBindingContainer bc = (DCBindingContainer)pageLifecycleContext.getBindingContainer();
if (bc != null) {
ControllerContext context = ControllerContext.getInstance();
ViewPortContext currentRootViewPort = context.getCurrentRootViewPort();
Exception exceptionData = currentRootViewPort.getExceptionData();
if (currentRootViewPort.isExceptionPresent()) {
currentRootViewPort.clearException();
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, exceptionData.getMessage(), null));
}
}
Open the page definition file of the page for which exception is to be handled and add ControllerClass="com.exception.CustomFacesPageLifeCycle" in the pageDefinition tag.
2) Controller Layer : To handle exception at controller layer, there are following two ways:
Handle exception using task flow exception handler
The exceptions inside task flow, which are thrown by the method call activity used inside it, can be handled by marking bean method/jspx page as exception handler.
Handle exception using custom exception handler
If the exception is not handled by taskflow exception handler, then create custom exception handler as follow.
Create a CustomExceptionHandler class by extending ExceptionHandler class and define the exception handling logic in handleException method.
public void handleException(FacesContext facesContext, Throwable throwable,
PhaseId phaseId) throws Throwable {
String error_message;
error_message = throwable.getMessage();
// Handle the exception if required, Otherwise re-throw by using "throw throwable;"
}
In order to register this custom exception handler, create a folder named "services" inside .adf\META-INF and inside that folder create a text file with name "oracle.adf.view.rich.context.ExceptionHandler" having content as the path of CustomExceptionHandler file with package structure, like:
com.exception.handler.CustomExceptionHandler
3) Application Layer: In order to handle the exception at master application level, which is having multiple number of projects, create a custom application life cycle and register our custom exception handler.
First create custom exception handler class, CustomErrorHandler, that extends DCErrorHandlerImpl and override the reportException method. This is described in the post above.
Now create CustomFacesLifeCycle class that extends FacesPageLifecycle class and override prepareModel method:
public void prepareModel(LifecycleContext lifecycleContext) {
if (!(lifecycleContext.getBindingContext().getErrorHandler() instanceof
CustomErrorHandler)) {
lifecycleContext.getBindingContext().setErrorHandler(new CustomErrorHandler(true));
}
super.prepareModel(lifecycleContext);
}
Handle exception of all the pages:
To handle binding layer exception for all the pages, extend the DCErrorHandlerImpl class and override the reportException method. Register this custom error handler class in DataBinding.cpx file under Application tag as follows:
ErrorHandlerClass="com.exception.handler.CustomErrorHandler "
public class CustomErrorHandler extends DCErrorHandlerImpl {
private String[][] overrideExceptions = {{"oracle.jbo.JboException", "CUST_001","This is custom JBO exception message."}};
public CustomErrorHandler (boolean setToThrow) {
super(setToThrow);
}
public CustomErrorHandler () {
this(true);
}
@Override
public void reportException(DCBindingContainer bc, Exception ex) {
BindingContext ctx = bc.getBindingContext();
String err_code = null;
if (ex instanceof TxnValException) {
// Handle JBO-27023
// Display exception message
}
if (ex instanceof oracle.jbo.DMLException) {
// Handle JBO-26061
// Display exception message } else if (ex instanceof oracle.jbo.JboException) {
// Display exception message
} else {
super.reportException(bc, ex);
}
}
@Override
protected boolean skipException(Exception ex) {
// Override this method to skip any exception.
return super.skipException(ex);
}
@Override
public String getDisplayMessage(BindingContext context,
Exception exception) {
//Override this method to return custom error message
return message;
}
}
Handle exception of individual page:
To handle exception for a single page, create a CustomFacesPageLifeCycle class that extends FacesPageLifecycle. Now override the reportErrors method:
public void reportErrors(PageLifecycleContext pageLifecycleContext) {
DCBindingContainer bc = (DCBindingContainer)pageLifecycleContext.getBindingContainer();
if (bc != null) {
ControllerContext context = ControllerContext.getInstance();
ViewPortContext currentRootViewPort = context.getCurrentRootViewPort();
Exception exceptionData = currentRootViewPort.getExceptionData();
if (currentRootViewPort.isExceptionPresent()) {
currentRootViewPort.clearException();
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, exceptionData.getMessage(), null));
}
}
Open the page definition file of the page for which exception is to be handled and add ControllerClass="com.exception.CustomFacesPageLifeCycle" in the pageDefinition tag.
2) Controller Layer : To handle exception at controller layer, there are following two ways:
Handle exception using task flow exception handler
The exceptions inside task flow, which are thrown by the method call activity used inside it, can be handled by marking bean method/jspx page as exception handler.
Handle exception using custom exception handler
If the exception is not handled by taskflow exception handler, then create custom exception handler as follow.
Create a CustomExceptionHandler class by extending ExceptionHandler class and define the exception handling logic in handleException method.
public void handleException(FacesContext facesContext, Throwable throwable,
PhaseId phaseId) throws Throwable {
String error_message;
error_message = throwable.getMessage();
// Handle the exception if required, Otherwise re-throw by using "throw throwable;"
}
In order to register this custom exception handler, create a folder named "services" inside .adf\META-INF and inside that folder create a text file with name "oracle.adf.view.rich.context.ExceptionHandler" having content as the path of CustomExceptionHandler file with package structure, like:
com.exception.handler.CustomExceptionHandler
3) Application Layer: In order to handle the exception at master application level, which is having multiple number of projects, create a custom application life cycle and register our custom exception handler.
First create custom exception handler class, CustomErrorHandler, that extends DCErrorHandlerImpl and override the reportException method. This is described in the post above.
Now create CustomFacesLifeCycle class that extends FacesPageLifecycle class and override prepareModel method:
public void prepareModel(LifecycleContext lifecycleContext) {
if (!(lifecycleContext.getBindingContext().getErrorHandler() instanceof
CustomErrorHandler)) {
lifecycleContext.getBindingContext().setErrorHandler(new CustomErrorHandler(true));
}
super.prepareModel(lifecycleContext);
}
Now create a CustomADFPhaseListener class that extends ADFPhaseListener class and Override the createPageLifecycle method to return a new custom lifecycle as follows .
public class CustomADFPhaseListener extends ADFPhaseListener {
protected PageLifecycle createPageLifecycle() {
return new CustomFacesLifeCycle();
}
}
Now register the CustomADFPhaseListener in the faces-config file, under Life Cycle tab.