5

我从 php 服务器取回数据,有时它会发出警告。这些警告会导致解析响应引发语法错误,该错误会违反我现有的所有 try/catch 代码并停止处理,从而使复杂对象处于无法恢复的部分状态。

我怎样才能捕捉到这些错误?我希望有机会让物体恢复到某种稳定状态。

理想情况下,我不会收到说我应该重新考虑架构或更改 php 设置的答案。我想知道如何响应 JSON.parse() 抛出的 SyntaxErrors。

谢谢你,杰罗迈耶斯

编辑:

我注意到这个问题比我最初想象的要复杂。这是没有捕获 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.

4

1 回答 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!"
于 2012-05-29T20:53:42.483 回答