【发布时间】:2009-10-28 11:07:46
【问题描述】:
我有一个运行良好的 jqgrid。
我想知道是否可以捕获服务器发送的错误?是怎么做的?
【问题讨论】:
我有一个运行良好的 jqgrid。
我想知道是否可以捕获服务器发送的错误?是怎么做的?
【问题讨论】:
如果您查看jqgrid demo site 并查看“3.2 版中的新增功能”,应该有一个关于控制服务器错误的部分。
具体来说,它使用了一个回调参数loadError:
loadError : function(xhr,st,err) {
jQuery("#rsperror").html("Type: "+st+"; Response: "+ xhr.status + " "+xhr.statusText);
}
正如上面 mcv 所述,一些错误是数据错误,因此您需要专门处理这些错误。
【讨论】:
我最近在我为 CB Richard Ellis(我的雇主)工作的原型项目中广泛使用了 jqgrid。有很多方法可以填充 jqgrid,如 documentation 中所述:(请参阅“检索数据”节点)。
目前我进行了一个服务调用,该调用返回一个 json 字符串,当评估该字符串时,会为我提供一个包含以下内容的对象:
在我的成功回调中,我像这样手动创建 jqgrid:(“数据”是我在评估返回的 json 字符串时得到的对象)。
var colNames = data.ColumnNames;
var colModel = data.ColumnModels;
var previewData = data.PreviewData;
var totalRows = data.TotalRows;
var sTargetDiv = userContext[0]; // the target div where I'll create my jqgrid
$("#" + sTargetDiv).html("<table cellpadding='0' cellspacing='0'></table>");
var table = $("#" + sTargetDiv + " > table");
table.jqGrid({
datatype: 'local',
colNames: colNames,
colModel: colModel,
caption: 'Data Preview',
height: '100%',
width: 850,
shrinkToFit: false
});
for (var row = 0; row < previewData.length; ++row)
table.addRowData(row, previewData[row]);
所以你可以看到我手动填充数据。有超过 1 种服务器错误。存在逻辑错误,您可以将其作为 json 字符串中的属性返回,并在尝试创建 jqgrid(或基于每行)之前检查。
if (data.HasError) ...
或者基于每行
for (var row = 0; row < previewData.length; ++row)
{
if (previewData[row].HasError)
// Handle error, display error in row, etc
...
else
table.addRowData(row, previewData[row]);
}
如果您的错误是服务器上未处理的异常,那么您可能需要在异步调用中进行错误回调。在这种情况下,(大概)正在创建 jqgrid 的成功回调将不会被调用。
当然,这适用于手动填充 jqgrid,这只是众多可用选项之一。如果您将 jqgrid 直接连接到服务调用或函数以检索数据,那么这完全是另一回事。
在文档页面上,查看基本网格 > 事件。在那里你会看到可能派上用场的“loadError”事件。
【讨论】:
使用回调。如果您收到实际的 http 错误(例如 400 或 500),则会触发 loadError(xhr, status, error)。
但某些错误(如验证)不应引发 400 或 500 错误。但是您仍然可以在 loadComplete(xhr) 中捕获它们。解析您的 json,并检查您用于识别错误的任何方式。例如,我在我的 loadComplete() 中这样做:
if (jsonResponse.errors) {
$.each(jsonResponse.errors, function(i, val){
addErrorMessage($("#"+val.field), val.message);
});
}
【讨论】:
您可以在 jqGrid 定义中使用loadError 事件(请参阅documentation)。例如:
//Catch errors
loadError = function(xhr, textStatus, errorThrown) {
var error_msg = xhr.responseText
var msg = "Some errors occurred during processing:"
msg += '\n\n' + error_msg
alert(msg)
}
【讨论】:
据我所见,它将数据作为 json 字符串返回。因此,您需要做的是添加一个错误处理程序,将错误格式化为 json 字符串并将其打印为一个。这可以在 php 中使用
set_error_handler
功能。
然后我猜错误处理程序会将数据推送到 jsonReturn.error 中,因此您只需要在将数据添加到表时进行检查。
如果您抛出异常而不是让它一直出错(可能是更好的做法),那么您可能希望将异常格式化为 json 字符串。
由于它以 xml 格式返回数据,因此您需要解析 xml:
<xml>
<error>
error message
</error>
</xml>
像这样:
$(request.responseXML).find("error").each(function() {
var error = $(this);
//do something with the error
});
无耻借用:http://marcgrabanski.com/article/jquery-makes-parsing-xml-easy
【讨论】:
要记住的另一件事/或者我发现的是,如果您使用的是 Asp.net,则需要转
在该部分中 - 这将允许您自省返回的消息。
【讨论】:
如果您使用带有选项的 jqGrid
ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
datatype: "json",
url: wsPath
通过 AJAX 和 Web 服务或 MVC 控制器加载数据,那么这个答案适合你。
注意,如果在处理 AJAX 调用的 web 方法中发生运行时错误,则无法通过 loadError 捕获,因为 loadError 只捕获 HTTP 相关的错误。您应该通过try ... catch 捕获web 方法 中的错误,然后使用return JsonString 在catch 块中以JSON 格式传递它。然后就可以在loadComplete事件中处理了:
loadComplete: function (data) {
if (this.p.datatype === 'json') {
if (data!==undefined && data!==null && isErrorJson(data)) {
ShowErrorDialog(getJsonError(data));
}
// ...
}
以上函数含义如下,根据需要实现:
isErrorJson(data):如果数据对象包含 Web 方法中定义的错误,则返回 truegetJsonError(data):返回带有您的网络方法中定义的错误消息的字符串ShowErrorDialog(msg):在屏幕上显示错误信息,例如通过 jQueryUI 对话框。在Web服务方法中你可以使用JavaScriptSerializer来创建这样一个错误对象,对于上面的2个JavaScript方法你可以使用jQuery函数$.parseJSON(data.d)从JSON对象中获取消息。
【讨论】:
function gridCroak(postdata, _url, grid, viewCallBack, debug) {
$(".loading").css("display", "block");
$.ajax({
type: 'POST',
url: _url,
data: postdata,
dataType: "xml",
complete: function(xmldata, stat){
if(stat == "success") {
$(".loading").css("display", "none");
var errorTag = xmldata.responseXML.getElementsByTagName("error_")[0];
if (errorTag) {
$("#ErrorDlg").html(errorTag.firstChild.nodeValue);
$("#ErrorDlg").dialog('open');
} else {
var warningTag = xmldata.responseXML.getElementsByTagName("warning_")[0];
if (warningTag) {
$("#WarningDlg").html(warningTag.firstChild.nodeValue);
$("#WarningDlg").dialog('open');
} else {
if (debug == true) {
alert(xmldata.responseText);
}
jQuery(grid)[0].addXmlData(xmldata.responseXML);
if(viewCallBack) viewCallBack();
}
}
} else {
$("#ErrorDlg").html("Servizio Attualmente Non Disponibile !");
$("#ErrorDlg").dialog('open');
}
}
});
}
在网格中
datatype : function(postdata) { gridCroak(postdata, 'cgi-bin/dummy.pl?query=stock',
"#list", null, false) },
最后它确实使用了我认为相同的方法。
谢谢大家
【讨论】: