Better handling of timelapse deletion errors

Closes #1975
This commit is contained in:
Gina Häußge 2017-06-27 11:32:42 +02:00
parent 0db323d0c5
commit f20185db3a
3 changed files with 48 additions and 13 deletions

View file

@ -7,6 +7,7 @@ __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms
import os
import threading
import logging
from flask import request, jsonify, url_for, make_response
from werkzeug.utils import secure_filename
@ -128,7 +129,12 @@ def deleteTimelapse(filename):
timelapse_folder = settings().getBaseFolder("timelapse")
full_path = os.path.realpath(os.path.join(timelapse_folder, filename))
if full_path.startswith(timelapse_folder) and os.path.exists(full_path):
os.remove(full_path)
try:
os.remove(full_path)
except Exception as ex:
logging.getLogger(__file__).exception("Error deleting timelapse file {}".format(full_path))
return make_response("Unexpected error: {}".format(ex), 500)
return getTimelapseData()

View file

@ -688,9 +688,14 @@ function showConfirmationDialog(msg, onacknowledge, options) {
* Will listen to the supplied promise, update the progress on .progress events and
* enabling the close button and (optionally) closing the dialog on promise resolve.
*
* The calling code should call "notify" on the deferred backing the promise and supply
* two parameters: the text to display on the progress bar and the optional output field and
* a boolean value indicating whether the operation behind that update was successful or not.
* The calling code should call "notify" on the deferred backing the promise and supply:
*
* * the text to display on the progress bar and the optional output field and
* a boolean value indicating whether the operation behind that update was successful or not
* * a short text to display on the progress bar, a long text to display on the optional output
* field and a boolean value indicating whether the operation behind that update was
* successful or not
*
* Non-successful progress updates will remove the barClassSuccess class from the progress bar and
* apply the barClassFailure class and also apply the outputClassFailure to the produced line
* in the output.
@ -784,7 +789,19 @@ function showProgressModal(options, promise) {
var counter = 0;
promise
.progress(function(text, success) {
.progress(function() {
var short, long, success;
if (arguments.length === 2) {
short = long = arguments[0];
success = arguments[1];
} else if (arguments.length === 3) {
short = arguments[0];
long = arguments[1];
success = arguments[2];
} else {
throw Error("Invalid parameters for showProgressModal, expected either (text, success) or (short, long, success)");
}
var value;
if (max === undefined || max <= 0) {
@ -796,8 +813,8 @@ function showProgressModal(options, promise) {
// update progress bar
progressBar.width(String(value) + "%");
progressTextFront.text(text);
progressTextBack.text(text);
progressTextFront.text(short);
progressTextBack.text(short);
progressTextFront.width(progress.width());
// if not successful, apply failure class
@ -809,9 +826,9 @@ function showProgressModal(options, promise) {
if (output && pre) {
if (success) {
pre.append($("<span class='" + outputClassSuccess + "'>" + text + "</span><br>"));
pre.append($("<span class='" + outputClassSuccess + "'>" + long + "</span><br>"));
} else {
pre.append($("<span class='" + outputClassFailure + "'>" + text + "</span><br>"));
pre.append($("<span class='" + outputClassFailure + "'>" + long + "</span><br>"));
}
pre.scrollTop(pre[0].scrollHeight - pre.height());
}

View file

@ -229,6 +229,16 @@ $(function() {
.done(function() {
self.markedForFileDeletion.remove(filename);
self.requestData()
})
.fail(function(jqXHR) {
var html = "<p>" + _.sprintf(gettext("Failed to remove timelapse %(name)s.</p><p>Please consult octoprint.log for details.</p>"), {name: filename});
html += pnotifyAdditionalInfo('<pre style="overflow: auto">' + jqXHR.responseText + '</pre>');
new PNotify({
title: gettext("Could not remove timelapse"),
text: html,
type: "error",
hide: false
});
});
};
@ -288,7 +298,7 @@ $(function() {
self._bulkRemove = function(files, type) {
var title, message, handler;
if (type == "files") {
if (type === "files") {
title = gettext("Deleting timelapse files");
message = _.sprintf(gettext("Deleting %(count)d timelapse files..."), {count: files.length});
handler = function(filename) {
@ -296,11 +306,13 @@ $(function() {
.done(function() {
deferred.notify(_.sprintf(gettext("Deleted %(filename)s..."), {filename: filename}), true);
})
.fail(function() {
deferred.notify(_.sprintf(gettext("Deletion of %(filename)s failed, continuing..."), {filename: filename}), false);
.fail(function(jqXHR) {
var short = _.sprintf(gettext("Deletion of %(filename)s failed, continuing..."), {filename: filename});
var long = _.sprintf(gettext("Deletion of %(filename)s failed: %(error)s"), {filename: filename, error: jqXHR.responseText});
deferred.notify(short, long, false);
});
}
} else if (type == "unrendered") {
} else if (type === "unrendered") {
title = gettext("Deleting unrendered timelapses");
message = _.sprintf(gettext("Deleting %(count)d unrendered timelapses..."), {count: files.length});
handler = function(filename) {