lucassus / extjs4-account-manager

Ext JS 4 and Ruby on Rails simple CRUD example

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Gracefully handle http errors

lucassus opened this issue · comments

Here's an implementation of graceful http error handling. Note that since I've failed to find in the official ExtJS docu how to find the http status of the ajax reply in the official API, the solution is based on looking at the returned "batch" object:

  1. in case of a HTTP error batch.exceptions[0].error.status is set and it's the HTTP status code

  2. it'd be nice to have access to the HTML page that rails returned, in order to display a detailed error however that data/text doesn't seem to be available

    failure: function(batch, options) {
      // extract server side errors
      var serverSideErrors = batch.exceptions[0].error;
    
      // server side error reported via HTTP error code
      if( typeof( serverSideErrors.status ) == "number" ) {
        alert("Saving has failed. " +
              "The server replied with status code " +
              String(serverSideErrors.status) +
              ":\n" +
              serverSideErrors.statusText);
              // unfortunately we don't know how to access
              // the HTML page that the server delivers
              // and that contains a comprehensive description
              // of the problem
      }
      // server side reported validation error via JSON object
      else {
    

etc.

I use an Exception class like this one.

Then in my Ext.application, for example, I 'observe' the exception event on proxies:

// Observe event exception on every data proxy
// http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.proxy.Server
Ext.util.Observable.observe(Ext.data.proxy.Server);
Ext.data.proxy.Server.on('exception', TM.util.Exception.StoreExceptionHandler);

Hello Francesco,

On Fri, 12 Apr 2013, Francesco Valente wrote:

I use an Exception class like this one.

Then in my Ext.application, for example, I 'observe' the exception event on proxies:

// Observe event exception on every data proxy
// http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.proxy.Server
Ext.util.Observable.observe(Ext.data.proxy.Server);
Ext.data.proxy.Server.on('exception', TM.util.Exception.StoreExceptionHandler);

Woah, what a nice solution!

I'm not sure I understand it all though - it looks to me as if it
would also catch errors sent via json messages from the rails backend -
i.e. rails validation errors? Thus with that solution one doesn't get the
"error-colored" form fields?

Another question - rails sends along a very nice HTML document describing
the problem in depth. Did you have a look at how to get a handle on it?
It'd be nice to display the rails error page, f.ex. in an iframe.

?

Thanks a lot for your code pointer, it made my day unexpectedly receiving
feedback and then such a nice one too!
*t

I'm not sure I understand it all though - it looks to me as if it
would also catch errors sent via json messages from the rails backend -
i.e. rails validation errors? Thus with that solution one doesn't get the
"error-colored" form fields?

Yes, it catches validation errors from the server side , and form fields' related errors too. But "error-colored" form fields still working as usually.

Another question - rails sends along a very nice HTML document describing
the problem in depth. Did you have a look at how to get a handle on it?
It'd be nice to display the rails error page, f.ex. in an iframe.

Do you refer to the flash messages returned in HTML? Well, I think the communication between client and server should occur via JSON messages. It's responsibility of the client to generate a proper HTML fragment to be rendered in the page... Think the use of a custom extjs component to be used in place of Ext.Msg to generate, for example, a popup that appear from the top of the page and disappear after few seconds.

On Sat, 13 Apr 2013, Francesco Valente wrote:

  Another question - rails sends along a very nice HTML document describing
  the problem in depth. Did you have a look at how to get a handle on it?
  It'd be nice to display the rails error page, f.ex. in an iframe.

Do you refer to the flash messages returned in HTML?

No, I'm referring to things like syntax and other errors in the code of
the rails backend, couldn't connect to database, errors from the database
etc. which all produce a html page as a result, that describes the error,
sometimes including a ruby stack trace and further explanations.

Well, I think the communication between client and server should occur
via JSON messages. It's responsibility of the client to
generate a proper HTML fragment to be rendered in the page... Think the
use of a custom extjs component to be used in place of Ext.Msg to
generate, for example, a popup that appear
from the top of the page and disappear after few seconds.

*t

Those kind of errors are very usefull for developers rather then for the end users, so generally in my rails applications I use an emailer that sends all those kind of informations, including stack traces, in a well formatted email to developers.
If you may be interested in, I usually handle client side errors (javascript) in the same manner too. I send the error catched through window.onerror via ajax to a rails action that logs the error into an email for developers. E.g.:

Ext.onReady(function() {
    function log2server(message) {
        Ext.Ajax.request({
            url: '/log_client_errors',
            method: 'POST',
            params: { error_message: message }
        });
    }

    function log2test(message) {
        if (window.CLIENT_SIDE_ERRORS_DEBUG) {
            if (typeof window.CLIENT_SIDE_ERRORS != "string")
                window.CLIENT_SIDE_ERRORS = ""
            window.CLIENT_SIDE_ERRORS += message+"\n";
        }
    }

    window.onerror = function(message, file, line) {
        var sFormattedMessage = '[' + file + ' (' + line + ')] ' + message;
        if (console)
            console.log("CATCHED CLIENT ERROR: "+sFormattedMessage);

        log2test(sFormattedMessage);
        log2server(sFormattedMessage);
    }
});