PDA

View Full Version : Event 'exception' of the AjaxProxy is called not in all cases when it is required



Qtx
27 May 2011, 1:34 PM
I missed the handler 'exception' of the Store, which was in the ExtJS 3. I found it now at the AjaxProxy. This event allows to catch up problems which might occur while loading the data over ajax:

- invalid URL
- empty response
- timeout
- user defined error

But one case, when it does not occur, but, in my opinion, it should occur, is the invalid data, which comes in the response. That is, either bad formatted json data or xml data. In this case, the process just breaks with a general unhandled exception and no event is called.

I would suggest to handle the parsing of the data and call the event 'exception' of the AjaxProxy in this case also. I slightly modified the method 'processResponse' to show how it could be done:


Ext.override(Ext.data.proxy.Ajax, {

processResponse: function(success, operation, request, response, callback, scope)
{
var me = this,
reader,
result,
records,
length,
mc,
record,
i;

if (success === true) {
try
{
reader = me.getReader();
result = reader.read(me.extractResponseData(response));
records = result.records;
length = records.length;

if (result.success !== false) {
mc = Ext.create('Ext.util.MixedCollection', true, function(r) {return r.getId();});
mc.addAll(operation.records);
for (i = 0; i < length; i++) {
record = mc.get(records[i].getId());

if (record) {
record.beginEdit();
record.set(record.data);
record.endEdit(true);
}
}

//see comment in buildRequest for why we include the response object here
Ext.apply(operation, {
response: response,
resultSet: result
});

operation.setCompleted();
operation.setSuccessful();
} else {
operation.setException(result.message);
me.fireEvent('exception', this, response, operation);
}
}
catch(ex)
{
operation.setException(ex);
me.fireEvent('exception', this, response, operation);
}
} else {
me.setException(operation, response);
me.fireEvent('exception', this, response, operation);
}

//this callback is the one that was passed to the 'read' or 'write' function above
if (typeof callback == 'function') {
callback.call(scope || me, operation);
}

me.afterRequest(request, success);
}

}); // Ext.data.proxy.Ajax
Now, the case of bad data format is also handled over the event 'exception' of the AjaxProxy.

Qtx
29 May 2011, 1:12 AM
The same applies for the forms. A parse error in the response data stops anything. Here is the example of the overridden Submit and Load actions, where the case parse error is also handled over the failure handler.


Ext.override(Ext.form.action.Submit, {

onSuccess: function(response) {
var form = this.form,
success = true,
result = false;

try
{
result = this.processResponse(response);
}
catch(ex)
{
this.failureType = 'parse'; // could be Ext.form.action.Action.PARSE_ERROR;
form.afterAction(this, false);
return;
}

if (result !== true && !result.success) {
if (result.errors) {
form.markInvalid(result.errors);
}
this.failureType = Ext.form.action.Action.SERVER_INVALID;
success = false;
}
form.afterAction(this, success);
} // onSuccess

}); // Ext.form.action.Submit

Ext.override(Ext.form.action.Load, {

onSuccess: function(response){
var result = false;
var form = this.form;

try
{
result = this.processResponse(response);
}
catch(ex)
{
this.failureType = 'parse'; // could be Ext.form.action.Action.PARSE_ERROR;
form.afterAction(this, false);
return;
}

if (result === true || !result.success || !result.data) {
this.failureType = Ext.form.action.Action.LOAD_FAILURE;
form.afterAction(this, false);
return;
}
form.clearInvalid();
form.setValues(result.data);
form.afterAction(this, true);
} // onSuccess

}); // Ext.form.action.Submit

Artur Bodera (Joust)
17 Nov 2011, 6:09 AM
Ext Team ? Hello?

I consider this a serious bug. Even though json reader defines "exception" event, it is not called on invalid data (which is an obvious and common exception).

Here is the buggy code from reader/Json.js


getResponseData: function(response) {
var data;
try {
data = Ext.decode(response.responseText);
}
catch (ex) {
Ext.Error.raise({
response: response,
json: response.responseText,
parseError: ex,
msg: 'Unable to parse the JSON returned by the server: ' + ex.toString()
});
}
//<debug>
if (!data) {
Ext.Error.raise('JSON object not found');
}
//</debug>


return data;
},


Here is how to reproduce:


// [...]
proxy: {

url: '/app.php',
reader: {
type: 'json',
}
}


inside app.php


<?php
echo "Any non-json garbage"; exit;

s.busch
16 Jan 2012, 6:24 AM
I agree that invalid JSON responses should be handled by Ext.data

We had those issues also and had to implement workarounds (custom readers etc.)