Uploadify: show error message from HTTP response - uploadify

If the server returns an error (HTTP response code != 200) when uploading a file with Uploadify, the uploaded file gets a red background and a message is show like this:
file.jpg (52.78KB) - HTTP Error
indicating that there was a HTTP Error. But that's not very useful to the the user. How can I make it show a more detailed error message? Like: 'Not a valid image' or 'Quota full'?
I was thinking of passing those messages in the HTTP response body, but Uploadify doesn't pick them up. Is there a known way to pass error messages back to Uploadify?

Take a look at these two posts in the uploadify forum on how to handle errors
onError to display what's happening
and
Upload script error reporting
there is a lot of useful info in there ..
Update
The following seems to do the trick for me ..
'onComplete': function(a, b, c, d, e){
if (d !== '1')
{
alert(d);
}
else
{
alert('Filename: ' + c.name + ' was uploaded');
}
}
coupled with this version of the uploadify script
<?php
if (!empty($_FILES))
{
$tempFile = $_FILES['userfile']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $_REQUEST['folder'] . '/';
$targetFile = str_replace('//','/',$targetPath) . $_FILES['userfile']['name'];
move_uploaded_file($tempFile,$targetFile);
switch ($_FILES['userfile']['error'])
{
case 0:
$msg = ""; // comment this out if you don't want a message to appear on success.
break;
case 1:
$msg = "The file is bigger than this PHP installation allows";
break;
case 2:
$msg = "The file is bigger than this form allows";
break;
case 3:
$msg = "Only part of the file was uploaded";
break;
case 4:
$msg = "No file was uploaded";
break;
case 6:
$msg = "Missing a temporary folder";
break;
case 7:
$msg = "Failed to write file to disk";
break;
case 8:
$msg = "File upload stopped by extension";
break;
default:
$msg = "unknown error ".$_FILES['userfile']['error'];
break;
}
}
if ($msg)
{ $stringData = "Error: ".$_FILES['userfile']['error']." Error Info: ".$msg; }
else
{ $stringData = "1"; } // This is required for onComplete to fire on Mac OSX
echo $stringData;
?>

Unfortunately the onUploadError event does not have access to the reponse body. You'll have to return 200 status and handle the errors in onUploadSuccess as far as I'm aware.
Here's how I'm doing it:
'onUploadSuccess' : function(file, data, response) {
var responseObj = JSON.parse(data);
if(responseObj.error_message)
{
$("#" + file.id).hide(); // this will hide the misleading "complete" message..
alert(responseObj.error_message);
return;
}
}
Or better yet you could replace the "complete" message with your error message like so:
'onUploadSuccess' : function(file, data, response) {
var responseObj = JSON.parse(data);
if(responseObj.error_message)
{
$("#" + file.id).find('.data').css('color', 'red').html(' - ' + responseObj.error_message);
return;
}
console.log(file, data, response);
}

I've had the same problem. after search for hours I found the problem. I have set "proxy server" in my "internet Options->Lan setting" , and when I returned it to default state, uploadify worked again.

For uploadify version 3.0+ take a look at the onUploadSuccess option - specifically the passed in variable named data - that will have whatever the server echoed. If you echo JSON remember to decode it like so:
...
'onUploadSuccess' : function(file, data, response) {
if (response){
var json_data=JSON.decode(data);
/* code here */
}
},
....

Related

NativeScript - Not getting any response from back-end with patch on NotFound()

On my back-end I got two possible responses within that action.
The first one:
return Ok(new { Message = "email_confirmed" });
And the second one:
return NotFound();
And on my front-end I got this:
let url: string = "http://10.0.2.2:53286/api/Home/AccountValidation?codeActivation=" + this.code;
this.http.patch(url, {
}).subscribe((res) => {
console.log(JSON.stringify(res));
if(res.status != 404) {
alert({title: "Sistema 3 Esferas", message: "¡Tu cuenta ha sido activada satisfactoriamente! :)", okButtonText: "¡Entendido!"});
this.router.navigate(["/Miembro"]);
} else {
this.btnEnabled = true;
alert({title: "Sistema 3 Esferas", message: "Has introducido un código inválido. :(", okButtonText: "Entiendo..."});
}
});
If the back-end reaches the Ok(), then the if gets executed and everything works perfectly.
However, if my back-end reaches the second return, which is the NotFound() one, nothing happens. You see this log at the beginning of the subscribe()?
console.log(JSON.stringify(res));
Well, if NotFound() is returned, nothing is showed on the log. It's almost like if the subscribe was never executed.
Why is that happening?
You need to add catch handler to catch all other responses than 200(OK) because they are treated as errors, like this -
this.http.patch(url, {
}).subscribe((res) => {
console.log(JSON.stringify(res));
alert({title: "Sistema 3 Esferas", message: "¡Tu cuenta ha sido activada satisfactoriamente! :)", okButtonText: "¡Entendido!"});
this.router.navigate(["/Miembro"]);
}).catch(this.handleError);
};
private handleError(error: any) {
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg);
this.btnEnabled = true;
alert({title: "Sistema 3 Esferas", message: "Has introducido un código inválido. :(", okButtonText: "Entiendo..."});
}
For more information, refer to this.

Ajax xMlHttpRequest.responseText not display what I set (very strange!)

I have a standard Ajax call with "Success" and "error". The error part is as straightforward as:
error: function (xMlHttpRequest, textStatus, errorThrown) {
errorLabel.text("ERROR: " + xMlHttpRequest.responseText); },
And in my C# backend, I saw someone recommend to use these code:
Response.StatusCode = 409; //as long as not 200
Response.Clear();
Response.Write(msg);
Response.End();
My errorLabel successfully display xMlHttpRequest.responseText after validation ON MY LOCAL DEV MACHINE.
However when I publish everything to a WINDOWS 2012 SERVER, there is no customized 'msg' in xMlHttpRequest.responseText anymore. Instead I got "The page was not displayed because there was a conflict" in responseText. (I could understand that status code 409 means there is a conflict.)
So how come it will perform like that when on a server ?? My own error message seems to have been replaced!
Thanks a lot!
*********************** C# Code ******************
[HttpPost]
public ActionResult DoSomething()
{
if (someconditiontrue)
{
return Json(new {value1=xxxx, value2=yyy})
}
else
{
Response.StatusCode = 409; //as long as not 200
Response.Clear();
Response.Write("my customized error message");
Response.End();
}
return Content(string.Empty);
}
I worked it around by not using "error" as returned result. Instead I still use Json { error = "my customized error message") object as result, and display corresponding validation message in "success: function(result){....}" block.

PhoneGap ajax call fails everytime

I am developing a mobile application using PhoneGap, and I have to access some services from another project.
I am using jquery-2.0.0.js and jquery-mobile-1.3.2.js.
$.ajax({
url: 'http://localhost:62465/api/account?email=johndoe#yahoo.com',
dataType: 'json',
success: function (data) {
alert(data.Name);
},
error: function (xhr, type) {
alert("Failed to load data");
alert(xhr + " " + type);
}
});
This ajax call fails everytime. In the config.xml I have the following line: <access origin="*" />
Where I might be going wrong!
The problem is that your phonegap application is requesting a local file from something that isn't a webserver. The local file is delivered with NO HTTP HEADERS - that means no "200 OK" header and no "404 Not Found" errors. So, the status code is assumed to be 0.
Straight javascript XHR will need to ignore status and perform your action on readystate == 4 (finished and ready). Like this:
var myrequest = new XMLHttpRequest();
myrequest.open('GET','localfile.html');
myrequest.onreadystatechange = function(){
if(myrequest.readyState == 4) {
var result = myrequest.responseText;
}
}
myrequest.send();
In MooTools, it's a relatively straightforward task of implementing an altered status test in the Request class - altering the return code test to also accept 0 for true. Like this:
Request.implement({
isSuccess: function(){
var status = this.status;
return ((status >= 200 && status < 300) || status === 0);
}
});
jQuery.... I have some things I'd like to say about jQuery - but I'll hold my tongue because this seems like a classy place.
To prepare jQuery for status == 0, you need to use the always event instead of the success event, you can test the status code there.
$.ajax({
url: '/echo/html/',
type: 'PUT',
data: "email=a#b.com"
}).always(function(data, textStatus, jqXHR){
switch(textStatus) {
case 200:
case 0:
alert('Success.');
break;
case 404:
alert('oops');
break;
}
});
Ajax in Cordova/Phonegap - Yay!
url of your query is localhost, thant means- the same device (android emulator or physical). I'm sure that this is your problem. You should use IP (or domain) of your api json server, maybe 192.168.1.1 (depending on your network configuration)
Are you using a physical device or an emulator ? iOS ? Android ?
I might be wrong, but if you're running your app on a mobile device you can't access to your localhost.
I solved the problem with the "GET" call, but now I am trying to make a "PUT" call and it's the same problem, always fails.
$.ajax({
url: '/echo/html/',
type: 'PUT',
data: "email=a#b.com",
success: function(data) {
alert('Success.');
}
});
If the url: 'http://localhost:62465/api/account?email=johndoe#yahoo.com' is not reachable from your mobile, there's a very useful trick to use.
With www.ngrok.com, you can assign an internet domain to your locally unreachable port.
Just signup, get an access token, and then you can use:
ngrok -authtoken myauthtoken -subdomain=mysubdomainname 62465
And then you can access your computer with the url http://mysubdomainname.ngrok.com/api/account?email=johndoe#yahoo.com
(For people with similiar problems)
Use ajax error to know what is wrong:
error: function(jqXHR, exception){
var msg = '';
if (jqXHR.status === 0) {
msg = 'Not connect.\n Verify Network.';
} else if (jqXHR.status == 404) {
msg = 'Requested page not found. [404]';
} else if (jqXHR.status == 500) {
msg = 'Internal Server Error [500].';
} else if (exception === 'parsererror') {
msg = 'Requested JSON parse failed.';
} else if (exception === 'timeout') {
msg = 'Time out error.';
} else if (exception === 'abort') {
msg = 'Ajax request aborted.';
} else {
msg = 'Uncaught Error.\n' + jqXHR.responseText;
}
console.log(msg);
}

uploadify : restrict image dimension

I am using Uploadify to upload image in php(codeigniter). Tested with the sample php file that come with the uploadify package. It works. However, I can't get onUploadError triggered. The sample php code has:
if (in_array($file_ext,$fileTypes)) {
$newFileName = mt_rand() . time() . '.' . $file_ext;
$targetFile = rtrim($targetPath,'/') . '/' . $newFileName;
move_uploaded_file($tempFile,$targetFile);
echo $newFileName;
} else {
echo 'Invalid file type.';
}
js is very simple as following:
$('#file_upload').uploadify({
'fileTypeDesc' : 'Image Files',
'fileTypeExts' : '*.gif; *.jpg; *.jpeg; *.png',
'swf' : '/static/uploadify/uploadify.swf',
'uploader' : '/static/uploadify/uploadify.php',
'onUploadError' : function(file, errorCode, errorMsg, errorString) {
console.log('The file ' + file.name + ' errorCode ' + errorCode + ' errorMsg ' + errorMsg + ' errorString ' + errorString);
},
'onUploadSuccess' : function(file, data, response) {
console.log(data);
}
});
when the Invalid file type. is echoed to the frontend. the onUploadSuccess is triggered instead of onUploadError. It seems odd to me that there is no indicator to stell uploadify there is an error from php.
the only way that triggers onUploadError is to set a non 200 http header before echoing. however, onUploadError function arguments errorCode, errorMsg, errorString are the http code and the echo content(error message) is lost.
UPDATES
I modified the question title so it speaks the real problem I was trying to solve. And I have since found the solution.
I finally got sometime to tackle this problem and here are my steps to solve it.
first, the problem of onUploadError is not fired is because the file has been uploaded successfully
second, uploadify queue limit and upload limit are updated accordingly upon successful upload regardless of detection of wrong image dimension from the backend.
So the solution is that my backend checks image dimension and responds with a json data with error message which shown to user. also reset uploadify, really it is swfupload, variable successful_uploads. that makes sure the queuelimit or upload limit not messed up. sample code:
'onUploadSuccess' : function(file, data, response) {
var obj = eval('(' + data + ')');
if ( obj.success ) { alert('uploaded') }
else {
var stats = this.getStats();
this.setStats({successful_uploads: stats.successful_uploads - 1});
}
}
see swfupload setStats method http://demo.swfupload.org/Documentation/#setStats

POSTing file information via ajax after upload using PlUpload

I'm using a customized example of plupload, where
one or more files are first uploaded to an Amazon S3 bucket, and
then file info + user-entered data (e.g. description) is POSTed
via ajax to my controller action in a loop.
This controller action then verifies that the file was upload to the S3 bucket and then saves the info into the database, returning a success or failure to the ajax call.
I use the 'UploadComplete' event to check for any upload errors, and if there are none, perform the actual POSTs in a loop.
What I'd like to do is wait until the entire loop has finished processing and then display the confirmation message (all success, all failed, mix of both) accordingly.
Current code:
uploader.bind('UploadComplete', function (up, files) {
var errorsPresent = false;
var errors = '';
// re-enable buttons
$('div.plupload_buttons a').removeClass('disabled');
$.each(uploader.files, function (i, file) {
if (errorDescArray.hasOwnProperty(file.id)) {
errorsPresent = true;
errors += errorDescArray[file.id] + '<br />';
}
else if (file.status = plupload.DONE) {
var jqXhr = $.post('/documents/add', {
'__RequestVerificationToken': $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val(),
'filename': file.name,
'size': file.size,
'location': $('#' + file.id + '_location').val(),
'description': $('#filedesc_text_' + file.id).text()
}).error(function (response) {
errorsPresent = true;
errors += response.responseText + '<br />';
});
}
});
//
if (errorsPresent) {
$('#uploadErrors').html('<div data-alert="alert" class="alert-message block-message fade in error">×<p>' + errors + '</p></div>');
}
else {
// set confirmation message
var message = files.length + ' file(s) were successfully uploaded.';
// clear file list
$('ul.plupload_filelist').html('');
// remove files from list
uploader.splice();
// hide modal
$('#upload-modal').modal('hide');
// show confirmation
$('#flashMessage').html('<div data-alert="alert" class="alert-message block-message fade in success">×<p>' + message + '</p></div>');
}
});
The above is obviously flawed in that the second half of the snippet doesn't really wait for the POSTs to complete, with the result that the success confirmation is displayed even if POST has an error response.
So my question is this: How do I perform an ajax post in a loop (unless there's a better way) and process the confirmation message after the loop has finished processing?

Resources