Skip to content

Commit

Permalink
Merge pull request #4522 from QualitativeDataRepository/4511-HTTP-Err…
Browse files Browse the repository at this point in the history
…ors-during-file-upload-not-caught

4511 http errors during file upload not caught
  • Loading branch information
kcondon authored Apr 26, 2018
2 parents 0e38c90 + 46a8fb0 commit c593125
Showing 1 changed file with 93 additions and 1 deletion.
94 changes: 93 additions & 1 deletion src/main/webapp/editFilesFragment.xhtml
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,110 @@
<!-- Upload -->
<ui:fragment id="fileUploadFragment" rendered="#{datasetPage || EditDatafilesPage.showFileUploadFragment()}">
<script>
//<![CDATA[
function uploadWidgetDropMsg() {
var fileUpload = $('div[id$="fileUpload"] div.ui-fileupload-content');
if ($(fileUpload).children('#dragdropMsg').length === 0) {
$(fileUpload).prepend('<div id="dragdropMsg">#{bundle['file.selectToAdd.dragdropMsg']}</div>');
}
}
function removeErrors() {
var errors = document.getElementsByClassName("ui-fileupload-error");
for(i=errors.length-1; i >=0; i--) {
errors[i].parentNode.removeChild(errors[i]);
}
}
function uploadStarted() {
// If this is not the first upload, remove error messages since
// the upload of any files that failed will be tried again.
removeErrors();
var curId=0;
//Find the upload table body
var files = document.getElementById("datasetForm:fileUpload").getElementsByTagName("tbody")[0];
//Add an id attribute to each entry so we can later match errors with the right entry
for(i=0;i< files.children.length;i++) {
files.children[i].setAttribute('upid', curId);
curId = curId+1;
}
//Setup an observer to watch for additional rows being added
var config={childList: true};
var callback = function(mutations) {
//Add an id attribute to all new entries
mutations.forEach(function(mutation) {
for(i=0; i<mutation.addedNodes.length;i++) {
mutation.addedNodes[i].setAttribute('upid',curId);
curId=curId+1;
}
//Remove existing error messages since adding a new entry appears to cause a retry on previous entries
removeErrors();
});
};
//uploadStarted appears to be called only once, but, if not, we should stop any current observer
if(observer !=null) {
observer.disconnect();
}
var observer = new MutationObserver(callback);
observer.observe(files,config);

$('button[id$="uploadStarted"]').trigger('click');
//alert("upload started");
}
function uploadFinished(fileupload) {
if (fileupload.files.length === 0) {
$('button[id$="AllUploadsFinished"]').trigger('click');
//alert("all uploads finished");
//stop observer when we're done
if(observer !=null) {
observer.disconnect();
observer=null;
}
}
}
function uploadFailure(fileUpload) {
// This handles HTTP errors (non-20x reponses) such as 0 (no connection at all), 413 (Request too large),
// and 504 (Gateway timeout) where the upload call to the server fails (the server doesn't receive the request)
// It notifies the user and provides info about the error (status, statusText)
// On some browsers, the status is available in an event: window.event.srcElement.status
// but others, (Firefox) don't support this. The calls below retrieve the status and other info
// from the call stack instead (arguments to the fail() method that calls onerror() that calls this function

//Retrieve the error number (status) and related explanation (statusText)
var status = arguments.callee.caller.caller.arguments[1].jqXHR.status;
var statusText = arguments.callee.caller.caller.arguments[1].jqXHR.statusText;
//statusText for error 0 is the unhelpful 'error'
if(status == 0) statusText='Network Error';

// There are various metadata available about which file the error pertains to
// including the name and size.
// However, since the table rows created by PrimeFaces only show name and approximate size,
// these may not uniquely identify the affected file. Therefore, we set a unique upid attribute
// in uploadStarted (and the MutationObserver there) and look for that here. The files array has
// only one element and that element includes a description of the row involved, including it's upid.

var name = arguments.callee.caller.caller.arguments[1].files[0].name;
var id = arguments.callee.caller.caller.arguments[1].files[0].row[0].attributes.upid.value;
//Log the error
console.log('Upload error:' + name + ' upid=' + id + ', Error ' + status + ': ' + statusText );
//Find the table
var rows = document.getElementById('datasetForm:fileUpload').getElementsByTagName('tbody')[0].children;
//Create an error element
var node = document.createElement("TD");
//Add a class to make finding these errors easy
node.classList.add('ui-fileupload-error');
//Add the standard error message class for formatting purposes
node.classList.add('ui-message-error');
var textnode = document.createTextNode("Upload unsuccessful (" + status + ": " + statusText + ").");
node.appendChild(textnode);
//Add the error message to the correct row
for(i=0;i<rows.length;i++) {
if(rows[i].getAttribute('upid') == id) {
//Remove any existing error message/only show last error (have seen two error 0 from one network disconnect)
var err = rows[i].getElementsByClassName('ui-fileupload-error');
if(err.length != 0) {
err[0].remove();
}
rows[i].appendChild(node);
break;
}
}
}
function dropBoxUploadFinished(fileupload) {
Expand All @@ -48,6 +138,7 @@
$(document).ready(function () {
uploadWidgetDropMsg();
});
//]]>
</script>
<p class="help-block">
<span class="glyphicon glyphicon-info-sign"/>
Expand Down Expand Up @@ -101,6 +192,7 @@
label="#{bundle['file.selectToAddBtn']}"
oncomplete="javascript:dataset_fileupload_rebind();uploadFinished(PF('fileUploadWidget'));"
onstart="javascript:uploadWidgetDropRemoveMsg();uploadStarted();"
onerror="javascript:uploadFailure();"
sizeLimit="#{EditDatafilesPage.getMaxFileUploadSizeInBytes()}"
fileLimit="#{EditDatafilesPage.getMaxNumberOfFiles()}"
invalidSizeMessage="#{bundle['file.edit.error.file_exceeds_limit']}"
Expand Down

0 comments on commit c593125

Please sign in to comment.