APEX Ajax Deadlock Bug

При работе с интерактивным отчетом в Oracle Application Express (APEX), в случае обрыва сети или возникновения ошибки в Oracle (т.е. как бы на сервере 500-е ошибки), все дальнейшие попытки выполнить какие-нибудь действия над интерактивным отчетом на странице будут завершаться с ошибкой.

Так продолжится, пока вы не обновите страницу полностью.
При этом, никаких сообщений, что надо обновить страницу, APEX пользователю не выдаст.
При обновлении теряются все данные, которые пользователь уже ввел для фильтрации, например!
Это крайне раздражает пользователей готового решения на Application Expres и начинают поступать многочисленные вопросы, аля - какого лешего мы не сдалали все на ASP.NET или на "Java".

Файл решения проблемы в APEX 3.2.
Этот баг остался в APEX 4 и мое решение нужно немного доделать для четверки. Если вы это сделаете, то буду благодарен, если вы перешлете мне для публикации.
Для workaround подключите в страницу APEX JavaScript фреймворк jQuery (для версии 3.2 и ранее).
Подключите на нужную страницу APEX JavaScript файл моего решения - apex_ajax_deadlock_treatment.js.
Это все можно сделать через шаблоны страниц.
В APEX 4 jQuery уже внедрен и нужно только немного подправить код только в одном месте.

Как получить этот баг:

  1. откройте любую страницу с интерактивным отчетом APEX.
    (APEX должне быть установлен на другом компьютере)

  2. разорвите подключение к нитернет (или как-то добейтесь, чтоб низлежащий запрос рвал).

  3. выполните любое действие над интерактивным отчетом - пейджинг, сортировка, фильтрация, изменение количества выводимых на странице строк и т.д.

  4. подключите интернет обратно.

  5. Страница с интерактивным отчетом станет "залочена", пока вы ее не обновите.

Это поведение связано с багом в JavaScript AJAX коде APEX.
Что происходит на низком уровне:
А там простая разработческая халтура!
При выполнении действия над интерактивным отчетом запускается AJAX запрос. По его завершении APEX ожидает получить HTML интерактивного отчета и вставляет полученный HTML на страницу, вместо старого.
Даже если AJAX завершился неудачно и полученные данные содержат не отчет, а HTML-страницу ошибки или сообщение об ошибке, делается попытка вставить эту "HTML-помойку" как интерактивный отчет.
Перед вставкой отчета APEX-JavaScript выполняет у элемента div , содержащего все относящееся к интерактивному отчету, замену id со значения "apexir_WORKSHEET" на "apexir_WORKSHEET_old".
Далее происходит исключение в строчке
(для APEX 3.2)
lThis=$u_js_temp_drop();$s(lThis,p.responseText);M.parentNode.replaceChild($x("apexir_WORKSHEET"),M)
Исключение появляется потому, что после замены id у старого элемента, новый не появился из-за того что полученный HTML содержит мусор!
Т.е. мы делаем в DOM следующий запрещенный прием - вставить в дерево DOM вместо какой-то ноды значение "null", что не допустимо:
M.parentNode.replaceChild($x( null, M)
Т.к. исключение никто не перехватил, то никто и не переименовал id у элемента обратно со значения "apexir_WORKSHEET_old" в значение "apexir_WORKSHEET".
После этого все действия над интерактивным отчетом, т.е. любой AJAX, будут рвать уже из-за того, что не удается найти div с id "apexir_WORKSHEET".

Вот такую мертвую петлю построил себе Oracle APEX.

Даже как-то обидно, что в APEX забыли сделать стандартную проверку, по имени "Всегда проверяй данные на входе, особенно полученные из базы данных". )))

Комментарии

Популярные сообщения из этого блога

A4tech. Мышь не найдена. Пожалуйста, подсоедините мышь.

SVN: Пропали иконки TortoiseSVN.

Вывод в cmd или bat пустой строки.