Получите доступ к интерактивному ответному ответу/отладчику Werkzeug при неудачном запросе AJAX на сервере TurboGears

В TurboGears имеется обратный люк, отличный интерактивный отладчик в браузере, основанный на Werkzeug Debugger. Когда отладка включена в конфигурации сервера, если запрос терпит неудачу, сервер отвечает интерактивной веб-страницей, где вы можете наблюдать трассировку Python, которая может быть проверена в интерактивном режиме.

Однако при разработке клиентских приложений в jQuery или AngularJS, как я могу получить доступ к интерактивному отладчику при сбое запроса AJAX?

2 ответа

Когда ваши запросы AJAX терпят неудачу на сервере, вы можете заменить содержимое текущего документа на документ отладки/ошибки из ответа сервера. Например, вы можете сделать что-то вроде следующего:

$.ajax({
 url: 'failing_controller/',
 type: 'POST'
})
 .fail(function _handleFailure(jqXHR, textStatus, errorThrown) {
 document.open();
 document.write(jqXHR.responseText);
 document.close();
 })
 .success(function _handleSuccess(data, textStatus, jqXHR) {
 // ... handle data ...
 });

Вероятно, вы захотите заменить обработчик отказа чем-то более подходящим в рабочей среде.


Приложение My Flask выполняется локально через сервер разработки Google App Engine. У меня есть сервер, настроенный на обслуживание статических файлов вне контекста приложения Flask, но запросы сценария Werkzeug Debugger должны проходить через приложение Flask. Я адаптировал mtr ответ на мою ситуацию:

// ...
.fail(function (jqXHR) {
 // open debugger in new window
 var endpointUrl = 'endpoint-url-of-your-ajax-request-without-query-params',
 debuggerWindow = window.open('', 'werkzeug debugger');
 debuggerWindow.document.open();
 debuggerWindow.location.href = endpointUrl;
 // set href after document.open() instead of before because
 // document.open() erases the path from the new window location href
 debuggerWindow.document.write(jqXHR.responseText);
 // now script requests in the HTML (i.e., in jqXHR.responseText) will
 // be made relative to endpointUrl rather than relative to the root path
 // and hence will go through the Flask app
 debuggerWindow.document.close();
})
// ...

ОБНОВИТЬ

Приведенный выше код работает только для запросов GET и только случайно. debuggerWindow.location.href= endpointUrl заставляет окно отправлять запрос GET на endpointUrl. Таким образом, вы получаете трассировку стека от второго запроса GET до endpointUrl.

Чтобы открыть исходную трассировку для любого типа запроса, я использую следующую реализацию (в ES6):

/*
thanks to:
 http://stackoverflow.com/a/3354511/1941513
 http://ilee.co.uk/changing-url-without-page-refresh/
 http://stackoverflow.com/a/4001415/1941513
 http://stackoverflow.com/a/11933007/1941513
 http://stackoverflow.com/a/3340186/1941513
*/
const werkzeugDebugger = (flaskResponse, url) => {
 if (!sameOrigin(url)) return;

 if(!confirm('__DEV__: Server Error! Open Werkzeug Debugger?')) return;

 window.history.pushState({}, 'Werkzeug Debugger', url);

 try {
 window.document.open();
 window.document.write(flaskResponse);
 }
 finally {
 window.document.close();
 }
};


/*
thanks to: https://gist.github.com/jlong/2428561
*/
const sameOrigin = url => {
 const parser = document.createElement('a');
 parser.href = url;
 return !parser.origin || parser.origin === window.location.origin;
};

Когда в режиме dev мой код проверяет, имеет ли ответ HTTP-статус на уровне 500. Если это так, он извлекает текст тела ответа (response.responseText для jQuery или response.text() для извлечения) и передает его и URL-адрес при вызове werkzeugDebugger.

licensed under cc by-sa 3.0 with attribution.