Flask Return action error logs to webserver
GeoDerp opened this issue · comments
In its current status the response message to the action is a status code Ex:
emhass/src/emhass/web_server.py
Line 55 in 78309ad
This however doesn't indicate if there was an error during action (and if there was, what was it). This only gives us the information that the action has completed (with an 201 code)
PR #190 implements alert box element that currently only facilitates JSON input format error:
emhass/src/emhass/templates/index.html
Lines 200 to 203 in 78309ad
I believe we could modify the return make_response(msg, 201)
to send back a 400 status code with an error log body (ex: as string[]) if something went wrong. we could then tell the JS to present the html alert box with the response error data. (helping the user understand why it crashed without viewing the logs)
js example being:
webserver.py (as an example)
return make_response(["testa","testb","testc"], 400)
index.html
emhass/src/emhass/templates/index.html
Lines 83 to 122 in 78309ad
to
async function formAction(action) {
var data = inputToJson()
if (data !== 0) { //don't run if there is an error in the data Json
showChangeStatus("loading") // show loading div for status
response = await fetch(`{{ basename }}/action/${action}`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data), //post can only send data via strings
}).then(saveStorage()) //save to storage if successful
showChangeStatus(response) //replace loading, show tick or cross
}
else {
showChangeStatus("remove") //replace loading, show tick or cross with none
}
}
//function in control of status icons of post above
function showChangeStatus(response) {
var loading = document.getElementById("loader") //element showing status
if (response.status === "remove") { //remove status icons
loading.innerHTML = "";
loading.classList.remove("loading");
}
else if (response.status === "loading") { //show loading logo
loading.innerHTML = "";
loading.classList.add("loading"); //append class with loading animation styling
}
else if (response.status === 201) { //then show a tick
loading.classList.remove("loading")
loading.innerHTML = `<p class=tick>✓</p>`
}
else { //then show a cross
loading.classList.remove("loading")
loading.innerHTML = `<p class=cross>⤬</p>` //show cross icon to indicate an error
document.getElementById("alert-text").textContent = "\r\n" + (await response.json()).split(',').join("\r\n") //This assumes the data is a string array
document.getElementById("alert").style.display = "block";
}
}
Originally posted by @GeoDerp in #190 (comment)
Some info I found here: https://flask.palletsprojects.com/en/2.3.x/api/#flask.Flask.make_response
I guess the hardest thing I haven't worked out is how to get in the app log of the action instance
I'm not certain but possibly some solutions here: https://stackoverflow.com/questions/66277372/writing-flask-console-logs-to-an-html-template-as-and-when-it-appears
Haven't looked into this. It may grab all console logs. I think we want to get just the ones from app.logger (in particular the ones related to the last ran action) although maybe we can filter before we send it out 🤔
If we can get the logs into the form of a string array I can pass it. Just have to work out how.
If I have some spare time I'll take a look at both of these issues I recently created. For now. I'll take a brake 👍