Обработка ошибок HTTP 4nn/5nn на стороне сервера, возвращающих весь HTML-документ в jQuery ajax-запросы

К моменту: как бы вы обрабатывали ошибки HTTP 4nn/5nn на стороне сервера в jQuery-запросах ajax? Этот случай касается веб-приложения JSP/Servlet на стороне сервера. Здесь я не говорю о тривиальных исключениях времени выполнения, таких как NullPointerException и т.д. Предположим, что все они отлично обработаны. Хорошим примером такой ошибки HTTP 4nn/5nn является 401 несанкционированный (недостаточные права пользователя) и 500 внутренних ошибок сервера (сбой базы данных, ошибка ввода-вывода, Error и т.д.). Предположим, что они не могут (или не должны) быть пойманы на уровне кодирования.

Сейчас я только что объявил <error-page> в web.xml для таких ошибок. Он в основном перенаправляет запрос на предварительно определенную страницу ошибок JSP/HTML, в которой конечный пользователь получает сообщение о серьезной ошибке и что пользователь может связаться с [email protected] для дальнейшей помощи. На этой же странице отображаются общие сведения об ошибке/исключении.

Он отлично работает в обычных HTTP-запросах, но как бы вы обрабатывали его в запросах XMLHtttp с использованием jQuery? Что лучше всего подходит для пользователей? Для меня это будет просто отображение всей страницы ошибки, как будто это обычный HTTP-запрос. Я решил это следующим образом:

function init() {
    $.ajaxSetup({
        error: handleXhrError
    });
}

function handleXhrError(xhr) {
    document.open();
    document.write(xhr.responseText);
    document.close();
}

Несмотря на то, что он работает отлично, мне кажется, что он взломан. Замена всего документа на содержимое страницы ошибок HTTP. Но так же, как вы будете следовать? Если нет, можете ли вы, может быть, уточнить, почему бы и нет, и как бы вы предпочли? Единственная альтернатива, которую я вижу, - это использование JS для отображения некоторого окна предупреждения/сообщения, чтобы информировать пользователя о неразрешимой ошибке, но пользователь может отклонить его и продолжить страницу, пока это невозможно.

Ответ 1

В конце концов, обращение к ошибкам в асинхронных запросах так же, как и к синхронным запросам, лучше всего подходит для пользователей. Только

function handleXhrError(xhr) {
    document.open();
    document.write(xhr.responseText);
    document.close();
}

завершится с ошибкой в ​​IE6/7/8, если у вас есть элементы <script>, которые необходимо загрузить и инициализировать. IE6/7/8 не будет этого делать. Чтобы заставить IE сделать это, вам в основном нужно сохранить текущий элемент <head> и только заменить его дочерние элементы на $("head").html(newHead). То же самое должно быть сделано для элемента <body>.

function handleXhrError(xhr) {
    var newDocument = xhr.responseText;
    $("head").html(newDocument.substring(newDocument.indexOf("<head>") + 6, newDocument.indexOf("</head>")));
    $("body").html(newDocument.substring(newDocument.indexOf("<body>") + 6, newDocument.indexOf("</body>")));
}

Отвратительно, но невозможно сделать $(xhr.responseText), когда текст ответа представляет целый HTML-документ с головой и телом. Не забудьте изменить индекс подстроки соответственно, если у вас есть некоторые атрибуты на <body> шаблона страницы ошибки (например, ID, класс и т.д.).

Ответ 2

Используйте диалог JQuery, например:

function handleXhrError(xhr) {
   ele = $("<div></div>").appendTo("body");
   ele.html(xhr.responseText);
   $(ele).dialog();

}

Я должен ответить на остальную часть того, что вы просили. Я бросаю и фиксирую определенные исключения, где могу, и отправляю специальные сообщения клиенту. Иногда я инструктирую клиента запустить функцию, которая может перенаправить браузер или частично обновить часть страницы. Это зависит от обстоятельств. Catching 400/500 будет иметь дело с реальными ошибками, но вы также хотите написать JS-код один раз, чтобы отфильтровать все ваши запросы AJAX для пользовательских флагов ошибок, которые вы вернетесь с сервера, посмотрите на эту страницу для более: http://www.bennadel.com/blog/1392-Handling-AJAX-Errors-With-jQuery.htm

Ответ 3

При необходимости вы также можете перенаправить на одну из предварительно определенных страниц ошибок, которые вы настроили с помощью window.location.href = "url-to-error-page";

Ответ 4

Я думаю, что лучше дать короткое сообщение, а не полностью переписывать вашу страницу. Таким образом, это не будет сильно мешать самой странице. Google Reader и Gmail делают что-то вроде этого. Reader показывает сообщение и не отмечает, что ваши данные читаются, но вы все равно можете прочитать все загруженные сообщения.

Ответ 5

Кажется, вы хотите сохранить рабочую страницу/приложение после получения условия ошибки, которое приведет к непригодному состоянию.

Я бы выполнил историю состояний на стороне клиента и вернул страницу в последнее полезное состояние, сообщив пользователю через заметный элемент на странице, что произошло.

Теория, связанная с этим, связана с транзакциями. Обычно поток выполнения:

  • Попросите менеджера транзакций начать транзакцию
    • Начать транзакцию
    • Состояние захвата
    • Возврат к вызывающему коду
  • Начать операции, которые являются частью транзакции
  • Об ошибке: указание диспетчер транзакций отменить транзакцию
    • Возвратить среду выполнения для состояния, указанного выше.
    • Отменить любые данные, которые больше не нужны (например, сериализация состояния)
  • При успешном выполнении: поручить диспетчеру транзакции совершить транзакцию
    • Завершение операций при транзакции по мере необходимости
    • Отменить любые данные, которые больше не нужны

Я не занимался серьезным изучением управления транзакциями в javascript. Поскольку вы заявляете, что ошибка на стороне сервера делает клиентскую сторону непригодной, возможно, есть способ реализовать части транзакции на стороне сервера. Важно, чтобы вы не оставляли вещи наполовину так, как на стороне клиента.

Задумывались ли вы о выполнении запроса "перед полетом", чтобы попытаться устранить эти проблемы, прежде чем клиентское приложение попытается выполнить настоящую работу?