Tuesday, November 25, 2014

Global exception handling Ajax calls in Ext JS

If your Ext JS web app primarily communicates with the backend via Ajax, then you need to handle server side exceptions for each of those Ajax calls. In my experience, doing this across all pages (it's not a single page application) is not an ideal solution, as it violates two (2) things:

  1. duplicates code 
  2. maintainance nightmare
The ideal solution is to have a global exception handler, where: 
  1. single location for all exception handling, 
  2. it acts as a catch-all
The solution I have here aims to globally:
  1. detect and inform user of Ajax operation timeout 
  2. handle Java session timeout when an Ajax call is executed on expired user session
  3. catch all Java exceptions from the backend
This is the code, put it in your common.js (or a similar file which you import in all your pages):
Ext.util.Observable.observe(Ext.data.Connection, {
    requestexception: function(conn, response, options) {
        if (response && response.request) {
            if (response.request.timedout) {
                Ext.Msg.show({
                    title: 'Operation Timeout',
                    msg: 'The operation did not complete due to a timeout.',
                    buttons: Ext.Msg.OK,
                    closable: false
                });

            } else {
                //then its a validation error or generic backend error 
                //this is my custom method, that parses the json response
                //and shows either: 
                //1. validation errors (ie. To Date must be before From Date)
                //2. runtime exceptions (generic system exceptions)
                showErrors(Ext.JSON.decode(response.responseText));
            }
        }
    },
    requestcomplete: function(conn, response, options, eOpts) {
        //using Spring Security, if user session expires,
        //it simply returns the login page
        if (response.responseText.indexOf('User') > -1 
            && response.responseText.indexOf('Password') > -1 
            && response.responseText.indexOf('Login') > -1) {
            window.location.href = 'login.htm';
        }
    }
});

This code registers a listener for the 2 events of the Ext.data.Connection:

  1. requestexception - non HTTP 200
  2. requestcomplete - HTTP 200
Ext.data.Connection is the underlying class used by the Ext JS classes such as Ext.data.Store, Ext.data.Model, Ext.Ajax, etc. Hence by registering this, any calls such as store.load() or model.save() which encounters backend error (non HTTP 200) or Ajax operation timeout or Java session timeout, will benefit from this global exception handling. 

No comments:

Post a Comment