Saturday, June 5, 2010

Handling Exceptions in Oracle UI Shell and Displaying Popup Error Message

Based on my previous blog post - Handling Exceptions in Oracle UI Shell and ADF Dynamic Regions, blog reader was asking - if it is possible to simplify provided sample application and show ViewController exception in lightweight Popup component, instead of closing all UI Shell tabs and rendering dynamic region. I did some research and answer is yes, possible. Today I will describe updated sample application, where exceptions are rendered in popup component, and UI Shell tabs are not closed as in previous implementation.

Download sample application - ADFIntegrationUIShell3.zip. This sample implements lightweight popup to render exception messages handled by ADF Task Flow exception handler activity.

If you will take a look into previous sample, from blog post above, you will notice key difference in Launcher bean getDynamicTaskFlowId() method. You will see that this method is simplified now - even in case of error, the same dynamic region (welcome region) will be rendered. In previous sample, in case of error, another dynamic region was rendered - error region. Its changed now, to render basic FacesMessage, instead of heavy dynamic region, in case off error:


Welcome region is declared as dynamic region, same as before:


This allows to re-execute getDynamicTaskFlowId() method, when error happens - because exception handler activity is declared on the same page where UI Shell is implemented. UI Shell page is pretty straightforward, it contains only reference to welcome dynamic region:


Thats it, we are ready to test now, but before doing test - let's check one small hint. In latest JDev 11g PS2, we got updated Fusion skin - fusion-11.1.1.3.0. This new skin version contains fixes for Tab components, I have noticed UI Shell tabs are rendered faster now. So, I have updated sample application to work with latest Fusion skin:


You can see, Tab components are rendered much better, and I should say that tabs are opening faster:


As per previous sample, Departments region contains broken reference to Commit operation, Save button generates exception. Let's test it and press Save button, now UI Shell tabs are not closed, but popup is rendered with information about exception:


User can close error popup and continue to work with the system, exception was cleared from ControllerContext programmatically:

19 comments:

HongMing said...

HI Andrejus

Thank you for you so quickly response and get the perfect result.

I have test your example and it works fine except that skin - fusion-11.1.1.3.0 can't be found in my environment. I am not sure whether this is due to my version 11.1.1.2.0?

Or do I need to upgrade my JDeveloper to 11.1.1.3.0?

Regards

HongMing Feng

Andrejus Baranovskis said...

Thats right, this skin is available only in 11.1.1.3.0. If you are running on 11.1.1.2.0, change it simply to fusion.

Regards,
Andrejus

Nachiket said...

Hi Andrejus,
I have tried to use this way of exception handling before as follows:

if(Exception){
FacesContext.getInstance().addMessage(..,..,..);
return TaskflowId.parse(TFId1);
}
else return TaskflowId.parse(TFId2);

Here I have 2 different return TFs . I observe that In case of an exception, the message gets queued, I am redirected to the intended page (TFId1) and then the exception popup shows up. I want it to be shown before being redirected & the next page should appear only when the user dismisses the popup by clicking OK. Is there a way to do it?

Thanks,
Nachiket Deo

Harleen said...

Hi
Where did you get the TabContext. I am unable to find "oracle.ui.pattern.dynamicShell.TabContext". Using 11.1.1.3.
Thanks

Andrejus Baranovskis said...

Hi,

It should be available by default, when you project contains a page based on UIShell template.

Can you compile my sample app?

Regards,
Andrejus

Harleen said...

Yes I am able to compile and run yours. I am trying to implement a similar thing on my ADF app but it won't read or import TabContext.
Please advise :-S

Harleen said...

Ahh I get it! But can it not be implemented with my own default template?

Harleen said...

Actually I take that back. I got it. =)

Harleen said...

Well your sample works well and fine. But I have an application of my own with a .jspx page that uses our own default template.
But for some reason the TabContext is still not recognized.
I even tried to create a new blank Oracle Dynamic shell template page but still same problem.
Any suggestions!?

Andrejus Baranovskis said...

Hi,

You can send me your sample app, I will check what is wrong :)

Andrejus

Harleen said...

It works again now.. don't understand what was amiss earlier!!
One more question..the popup error that comes up, is there a way to make the output message custom?
Thanks
=)

Kasapi said...

Hi Andrejus .
Your example is perfect , I just got one thing , where is the popup component that gets displayed ? I can find its binding in the Launcher backing bean but I can't find the component it self

Andrejus Baranovskis said...

Hi,

Popup doesnt exist on the page, its JSF information window, its rendered directly from Launcher bean.

Andrejus

Kasapi said...

Many Thanks Andrejus , so its the one launched by "facesContext.addMessage" , I got excited when I saw the the button in end of the popup , because I am in a case that need an error handling without leaving the page and displaying a popup with the error BUT also to have button to send an email or do some logic and some links under the error too to offer alternative for other pages other than the one that failed

Kasapi said...

So is it possible to make the message displayed customized add more buttons for example ?

Andrejus Baranovskis said...

This blog post is developed based on my sample app - http://jjzheng.blogspot.com/2011/03/using-popup-to-confront-user-to.html

It is for slightly different use case, but still similar principle as you are looking for popup.

Hope it will help.

Andrejus

Ahmed said...

Hi Andrejus , actually I was trying to do the custom popup solution and it worked then I just saw the link you posted , I added a custom error handler on the binding container level , and another on the controller level "your example" and I added customized popup on the root jsf pages in the application that got the root regions , then added your error handling template to the root regions , now the following errors are caught :
1- any error in the AM .
2- any error in the AM methods or backing bean methods that are on task flows.

whats not being caught by the custom error handlers are :
1-any bean method that are referenced directly by Action or Action listener on button or link.
2-any problem in the binding references in the page def .
I am very interested to know how to handle errors of methods referenced directly by Action or Action listeners .
Thanks in Advance
Kasapi

Andrejus Baranovskis said...

Hi,

1 - If bean method is calling invalid binding - DCErrorHandler will catch JboException from Model. If your bean method just plain Java, use try/catch - standard Java exception handling

2 - Is catched by DCErrorHandler class

Andrejus

Ahmed said...

Hi Andrejus many thanks that what I did , I added in the catch of the bean method to call that popup and pass to it the Exception message , hoped for more automated solution but I can't complain if this one works too . I think I still have sometime to understand how really the ADF framework works :)