5

I get data back from a php server and sometimes it tosses in warnings. These warnings cause the parsing of the response to throw a syntax error which defies all try/catch code I have in place and just stops processing, leaving complex objects in partial states that can't be recovered.

How can I catch these errors? I want to have a chance to get the object back into some steady state.

Ideally, I would not receive answers stating that I should rethink architecture or change php settings. I would like to know how to respond to SyntaxErrors being thrown by JSON.parse().

Thank you, Jeromeyers

EDIT:

It has come to my attention that the problem is more complex than I originally thought. This is the code that doesn't catch the SyntaxError:

generateSubmissionSuccessCallback: function (reloadOnSave) {
    var self = this;

    var submissionCallback = function(response) {
        var processingError = false;

        try
        {
            var responseObject = {};
            if (self.isAspMode())
            {
                if (typeof response !== 'object') // Chrome auto-parses application/json responses, IE & FF don't
                {
                    response = JSON.parse(response);
                }

                responseObject = {
                    entity: response.Payload,
                    success: response.Success,
                    message: response.Exception
                };

                if (jQuery.isArray(response.ValidationErrors))
                {
                    responseObject.message += ' \r\n\r\nValidation Errors\r\n';
                    for (var i = 0, maxi = response.ValidationErrors.length; i < maxi; i++)
                    {
                        var error = response.ValidationErrors[i];
                        responseObject.message += error.Error + '\r\n';
                    }
                }
            }
            else
            {
                responseObject = JSON.parse(response);
            }

            if (!responseObject || (responseObject.success !== undefined && responseObject.success !== true))
            {
                processingError = true;
                var message = responseObject ? responseObject.message : response;
                ErrorHandler.processError(
                    'An attempt to save failed with following message: \r\n' + message,
                    ErrorHandler.errorTypes.clientSide,
                    null,
                    jQuery.proxy(self.validatingAndSubmittingFinallyFunction, self));
            }
            else
            {
                // If this is a parent metaform, reload the entity, otherwise, close the metaform
                if (self.metaformType === 'details')
                {
                    if (self.substituteWhatToDoAfterSavingCallback)
                    {
                        self.substituteWhatToDoAfterSavingCallback(responseObject);
                    }
                    else if (reloadOnSave)
                    {
                        self.reloadCurrentEntity(true, responseObject.entity);
                    }

                    if (self.doesViewOutlineDefinePostSaveHook())
                    {
                        self.viewOutline.functions.postSaveHook(self);
                    }
                }
                else if (self.metaformType === 'childDetails')
                {
                    // Reload the Grid by which this form was made
                    if (self.associatedGridId)
                    {
                        Metagrid.refresh(self.associatedGridId);
                    }

                    if (self.parentMetaform.associatedGridId && self.childPropertyName)
                    {
                        var annotation = self.parentMetaform.getAnnotationByPropertyName(self.childPropertyName);
                        if (annotation && annotation.hasPropertyOptions('updateParentMetaformAssociatedGrid'))
                        {
                            Metagrid.refresh(self.parentMetaform.associatedGridId, self.parentMetaform.entityId);
                        }
                    }

                    if (self.substituteWhatToDoAfterSavingCallback)
                    {
                        if (self.doesViewOutlineDefinePostSaveHook())
                        {
                            self.viewOutline.functions.postSaveHook(self);
                        }

                        self.substituteWhatToDoAfterSavingCallback(responseObject);
                    }
                    else
                    {
                        if (self.doesViewOutlineDefinePostSaveHook())
                        {
                            self.viewOutline.functions.postSaveHook(self);
                        }

                        self.disposeMetaform();
                    }
                }
            }
        }
        catch (ex)
        {
            processingError = true;
            ErrorHandler.processError(
                "Please immediately inform the authorities that: \r\n\r\n" + typeof response === 'string' ? response : JSON.parse(response) + "\r\n\r\nand:\r\n\r\n " + ex.message,
                ErrorHandler.errorTypes.clientSide,
                null,
                jQuery.proxy(self.validatingAndSubmittingFinallyFunction, self));
        }
        finally
        {
            // If we are reporting an error to the user then we can't reset these state variables
            // because in the case where this is a child form, the parent will close the form
            // before the user has read the error.
            if (!processingError)
            {
                self.validatingAndSubmittingFinallyFunction();
            }
        }
    };

    return jQuery.proxy(submissionCallback, self);
}

There's really a lot going on in there, and a lot of structure that it fits into. I don't know if including it will really help.

3
  • 6
    Do you have control of the PHP server. It'd be much much better to fix this server side than client side. Commented May 29, 2012 at 20:45
  • Absolutely. I definitely I want know how to handle errors in parsing JSON. My grandpa always said, don't trust other drivers. I have generalized that, and I don't trust other systems. I deal with many systems. I want to know how to defend my code against nonsense data coming back when I would otherwise expect JSON.parse() to work or a try/catch to actually catch errors. Commented May 29, 2012 at 20:51
  • IOW, I ended my question stating that I didn't want answers relating to changing PHP. Yet I still got them. When I request javascript, I expect javascript, but actually, not really. Experience has taught me to expect any old thing and I would like to know that I have the implemented the means to handle it. I want to know how to catch SyntaxErrors in javascript. Commented May 29, 2012 at 20:54

1 Answer 1

4

Assuming you are talking about JSON and it raising an error (and not actual JavaScript being served to the page):

var data;
try{
  data = JSON.parse(jsonString);
}catch(e){
  // handle the error here, if you like
}
if (typeof data !== "undefined"){
  // Yay, we got some!
}

Read more about try...catch at MDN.

For example (from Chrome's console):

> try{ JSON.parse('3/') }catch(e){ console.log('oh no!') }; console.log('OK!')
"oh no!"
"OK!"
Sign up to request clarification or add additional context in comments.

11 Comments

might want to do (typeof data != "undefined")
@AlexMA Good point, will edit. (I'm used to using Ruby's JSON library which (properly?) does not allow you to parse JSON values, but only JSON documents (which must be either an array or object at the root level) and thus an empty string or 0-valued number are not possible.
It does work. Open the console and type:try{ data = JSON.parse('{"foo":"bar"}'); }catch(e){ console.log("it didn't work") } if (typeof data != "undefined"){ console.log("it did work!") }. Then try it with bad JSON.
@jeromeyers (a) It's not obvious, but I hope you won't be offended by that. (b) It does work, in my tests. See my edit. If you can reproduce something simple that doesn't work for you, create a JSFiddle for it and describe the OS/browser/version where it fails.
Odd, because in another context, in Chrome, the following code most definitely does not catch: try { responseObject = JSON.parse(response); } catch (e) { throw Error(e.message); }
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.