PDA

View Full Version : Where to trap Store / Proxy exception?



Bucs
13 Mar 2011, 5:20 AM
Having a heck of time trying to find out where to trap an exception when the server returns a JSON object that has a root success property set to false, object returned look like:



{"success":false,"Message":"The remote server returned an error: (500) Internal Server Error."}


I have a DataView configured with a Store and a Proxy to return a JSON object collection. Everything works great so long as the collection object is populated successfully. When there is an error on the server, I am creating and returning the above JSON object (which I can verify in the XHR request for Chrome), but the "load" listener on the store no longer handles the returned error object. I have tried listening to "exception" on the reader and proxy, how/where do I handle this request error?

Thanks.

Bucs
13 Mar 2011, 6:41 AM
Ok, apparently if the reader is setup with "root" object, you need to ensure that your returned object includes that node or you get an error in the readRecords method Ext.data.Reader. This seems a little odd to me though, why not check the "success" property of the passed in object first, before trying to do a getRoot()? That way, I can return the simple error JSON object with a success: false rather than having to return the full but empty root object?

Sencha code:


readRecords: function (data) {
/**
* The raw data object that was last passed to readRecords. Stored for further processing if needed
* @property rawData
* @type Mixed
*/
this.rawData = data;

data = this.getData(data);

var root = this.getRoot(data),
total = root.length,
success = true,
value, records, recordCount;

if (this.totalProperty) {
value = parseInt(this.getTotal(data), 10);
if (!isNaN(value)) {
total = value;
}
}

if (this.successProperty) { <--- Why not move this above the getRoot() and return if false? Just a thought...
value = this.getSuccess(data);
if (value === false || value === 'false') {
success = false;
}
}
........

glarotech
14 Mar 2011, 2:07 AM
hi

I've exactly the same setup and I've the same "problems".
Where do I catch the exceptions?!?

All HTTP error exceptions (e.g. return code 404) can be handled by the fired 'exception' handler.
But how to handle the successProperty or invalid JSON data?

No response at all :(

- domi

Bucs
14 Mar 2011, 4:21 AM
Well, if there is no HTTP error, then the way the readRecords is currently written for Ext.data.Store, it appears that you need to return the a root object that has the same name as the configured proxy's 'root' property, otherwise it fails in that method and never comes back. IMO, this is a bug as the method should check the successProperty before looking for the root node, otherwise you are forced to return the root node even in error scenarios.

You can check the success property of the returned data if the load event of the store is successfully fired by doing something like this:


load: function (store, recs, success) {
// Get data object that holds returned JSON
var jsonResult = store.proxy.reader.jsonData;

// Check for errors and display if needed
if (!jsonResult.success) {


But if there is an error in the readRecords in the Touch library...it doesn't appear to fire the 'exception' event if listened to on the proxy, reader, OR store.

glarotech
14 Mar 2011, 5:59 AM
thank you!

this seems to be a serious bug...
but how do you handle a malformed JSON response?

I'm still looking for a "how to handle exceptions in Sencha Touch" document... IMHO it's a pain in the ass w/ Sencha Touch!

- domi

Bucs
14 Mar 2011, 6:04 AM
I totally agree with you, and the Touch forum is not well monitored by Sencha staff, so probably going to have to open a ticket to get answer. I see that you are a Premium Member so you should be able to do that right?

Just make sure you post back here when you get an answer :)

glarotech
21 Mar 2011, 6:39 AM
just want to let you know:

I've still some problems with the exception handling, but I haven't opened a ticket so far.
I'll get to this part later and if I've no solution at this time, I'll open a ticket.

Of course, I keep you posted ;)

btw.: it's really quiet here and in the premium support forum too. there are others, looking for the sencha team...

- domi

glarotech
6 Apr 2011, 5:00 AM
(bump)

glarotech
27 Apr 2011, 6:53 AM
And here's the answer:


Ext.override(Ext.data.JsonReader, {
getResponseData: function(response) {
try {
var data = Ext.decode(response.responseText);
}
catch (ex) {
//throw 'Ext.data.JsonReader.getResponseData: Unable to parse JSON returned by Server.';
Ext.Msg.alert('Error', 'damn it');
}

if (!data) {
//throw 'Ext.data.JsonReader.getResponseData: JSON object not found';
Ext.Msg.alert('Error', 'damn it');
}

return data;
}
});

- domi

Bucs
27 Apr 2011, 6:59 AM
Nice, so what event are you listening to for trapping malformed JSON errors, the exception event of the store?

danderson
12 May 2011, 7:23 AM
I was having a similar issue with the following error being thrown when the response does not include the defined root:

Uncaught TypeError: Cannot read property 'length' of undefined

I'm using the following override to get around the error, of course YMMV



Ext.override(Ext.data.Reader, {
readRecords: function(data){
this.rawData = data;

data = this.getData(data);

var root = this.getRoot(data);
//BEGIN OVERRIDE - insert empty root if one does not exist
if (root == undefined) {
var rootName = this.root;
data[rootName.toString()] = new Array();
root = this.getRoot(data);
}
//END OVERRIDE
var total = root.length, success = true, value, records, recordCount;

if (this.totalProperty) {
value = parseInt(this.getTotal(data), 10);
if (!isNaN(value)) {
total = value;
}
}

if (this.successProperty) {
value = this.getSuccess(data);
if (value === false || value === 'false') {
success = false;
}
}

records = this.extractData(root, true);
recordCount = records.length;

return new Ext.data.ResultSet({
total: total || recordCount,
count: recordCount,
records: records,
success: success
});
}
});

Mis63
30 May 2011, 11:47 PM
I am having the same problem.
The success property of JSON response.

Can Sencha team tell us more about this : how to detect error sent in JSON response ?
Is a fix planned ?

bclinton
10 Jun 2011, 6:40 PM
I am having the same problem.
The success property of JSON response.

Can Sencha team tell us more about this : how to detect error sent in JSON response ?
Is a fix planned ?

I don't know if this was the best place to put it, but I was able to check the success property in the readRecords method before the superclass.readRecords was called in an override like this:

(code added to the original method in red)



Ext.override(Ext.data.JsonReader, {
readRecords: function(data) {
//this has to be before the call to super because we use the meta data in the superclass readRecords
if (data.metaData) {
this.onMetaChange(data.metaData);
}

if (!data.success)
{
Ext.Msg.alert('Error', 'Success was false', Ext.emptyFn);
}

/**
* DEPRECATED - will be removed in Ext JS 5.0. This is just a copy of this.rawData - use that instead
* @property jsonData
* @type Mixed
*/
this.jsonData = data;

return Ext.data.JsonReader.superclass.readRecords.call(this, data);
}
});


I originally bypassed the "return Ext.data.JsonReader.superclass.readRecords.call(this, data);" line when success was false, but this gave me the "Uncaught TypeError: Cannot read property 'length' of undefined" error in the store.

To avoid this error I make sure I add an empty array for the store's root (in my case "rows") so my json looks like this:


{
"success":false,
"msg":"Your session has expired. You will be redirected to the login page.",
"rows":[]
}

interfasys
15 Jun 2011, 12:17 PM
None of these solutions will catch syntax errors thrown when the JSON object has a big problem. Does Sencha Touch provide a way to catch these other than using the window object?

iamcam
30 Aug 2011, 9:17 AM
In response to @danderson's override. It works great, and I intend to keep it around until that time if/when Sencha changes the reader to handle these situations better.

katamshut
15 Sep 2011, 8:16 AM
hi

you can do the following to catch any "success: false":



this.store.load({
scope : this,
callback: function(records, operation, success) {
//the operation object contains all of the details of the load operation
if(operation.resultSet.success){
this.index();
} else {
Ext.Msg.alert('Failure','there was a failure: success is false');
}
}
});


cheers
katam