У меня есть jqgrid, который работает очень хорошо.
Мне было интересно, можно ли поймать ошибки, отправленные сервером? как это делается?
У меня есть jqgrid, который работает очень хорошо.
Мне было интересно, можно ли поймать ошибки, отправленные сервером? как это делается?
Недавно я широко использовал jqgrid для прототипа проекта, над которым я работаю для CB Richard Ellis (мой работодатель). Существует множество способов заполнения jqgrid, как указано в документации: (см. узел "извлечение данных").
В настоящее время я делаю вызов службы, который возвращает строку 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, подключенный непосредственно к вызову службы или функции для извлечения данных, то это совсем другое.
На странице документации посмотрите в разделе Basic Grids > Events. Там вы увидите событие «loadError», которое может пригодиться.
Если вы посмотрите на демонстрационный сайт jqgrid и посмотрите на "Что нового в версии 3.2" Там должен быть раздел об управлении ошибками сервера.
В частности, он использует параметр обратного вызова loadError:
loadError : function(xhr,st,err) {
jQuery("#rsperror").html("Type: "+st+"; Response: "+ xhr.status + " "+xhr.statusText);
}
Как указано выше в mcv, некоторые ошибки являются ошибками данных, поэтому вам нужно будет обрабатывать их специально.
Используйте обратные вызовы. Если вы получаете реальную ошибку 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);
});
}
Вы можете использовать событие loadError
в определении jqGrid (см. документацию). . Например.:
//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 и веб-сервисы или контроллеры MVC, тогда этот ответ для вас.
Обратите внимание: если в веб-методе, связанном с вызовом AJAX, возникает ошибка времени выполнения, ее нельзя перехватить с помощью loadError, поскольку loadError перехватывает только ошибки, связанные с HTTP. Вам лучше поймать ошибку в веб-методе через try ... catch
, а затем передать ее в формате JSON в блоке catch с помощью return JsonString
. Затем это можно обработать в событии loadComplete:
loadComplete: function (data) {
if (this.p.datatype === 'json') {
if (data!==undefined && data!==null && isErrorJson(data)) {
ShowErrorDialog(getJsonError(data));
}
// ...
}
Функции выше имеют следующий смысл, реализуйте их по мере необходимости:
isErrorJson(data)
: возвращает true, если объект данных содержит ошибку, как определено в вашем веб-методе.getJsonError(data)
: возвращает строку с сообщением об ошибке, как определено в вашем веб-методе.ShowErrorDialog(msg)
: отображает сообщение об ошибке на экране, например. через диалог jQueryUI.В методе веб-службы вы можете использовать JavaScriptSerializer
для создания такого объекта ошибки, для двух приведенных выше методов 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) },
В конце концов, я думаю, он использует тот же подход.
Спасибо всем