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:

  1. 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

    ReplyDelete
  2. 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

    ReplyDelete
  3. 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

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

    ReplyDelete
  5. 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

    ReplyDelete
  6. 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

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

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

    ReplyDelete
  9. 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!?

    ReplyDelete
  10. Hi,

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

    Andrejus

    ReplyDelete
  11. 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
    =)

    ReplyDelete
  12. 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

    ReplyDelete
  13. Hi,

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

    Andrejus

    ReplyDelete
  14. 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

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

    ReplyDelete
  16. 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

    ReplyDelete
  17. 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

    ReplyDelete
  18. 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

    ReplyDelete
  19. 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 :)

    ReplyDelete