My Flask application is running locally through Google App Engine's development server. I have the server configured to serve static files from outside the Flask app's context, but Werkzeug Debugger's script-file requests need to go through the Flask app. I have adapted mtr's answer to my situation:
// ...
.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's 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();
})
// ...
UPDATE
The code above works only for GET requests and only incidentally. debuggerWindow.location.href = endpointUrl
causes the window to submit a GET request to endpointUrl
. So you end up with the stack trace from a second GET request to endpointUrl
.
To open the original traceback for any type of request, I am using the following implementation (in 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;
};
When in dev mode, my code checks whether a response has a 500-level HTTP status. If so, it extracts the text of the response body (response.responseText
for jQuery or response.text()
for fetch) and passes it and the URL in a call to werkzeugDebugger
.