I have strange error that sometimes occurs on my WinJS app on the Windows Phone 8.1 512MB RAM Emulator. I couldn't reproduce it on other Emulator instances or on device.
The execution runs through the promise chain and finishes the following return statement:
return ( currentUpload = uploadOperation.startAsync() );
After that nothing happens. I set breakpoints at all three functions (success, failure, pending) that are given to the .then definition. None of these three function code will ever be reached when this strange case occurs.
I also put this return statement on a try catch block but there was no exception to catch.
short explanation of code:
Background Uploader instance is created (custom headers + PUT method)
StorageFile is opened by URI
Background uploader prepares upload of that file (definition of uploadOperation)
uploadOperation will be started
see full code:
var currentUpload; // global
function uploadFile(localFullPath, headers, serverUrl)
{
var fileUri = new Windows.Foundation.Uri('ms-appdata:///local' + localFullPath),
uploader = false;
try
{
uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();
uploader.method = 'PUT';
// set headers to uploader
for (var key in headers)
{
if (headers.hasOwnProperty(key))
uploader.setRequestHeader(key, headers[key]);
}
}
catch (e)
{
// error handling
return false;
}
Windows.Storage.StorageFile.getFileFromApplicationUriAsync(fileUri)
.then(function success(file)
{
return uploader.createUpload(serverUrl, file);
},
function failure(error)
{
return WinJS.Promise.wrapError('file not found');
})
.then(function (uploadOperation)
{
if (currentUpload == 'Canceled')
return WinJS.Promise.wrapError('upload canceled');
else
return ( currentUpload = uploadOperation.startAsync() );
})
.then(function success(success)
{
currentUpload = false;
// success handling
return true;
}, function failure(error)
{
currentUpload = false;
// error handling
return false;
}
}, function pending(status)
{
var progress = status.progress,
percent = Math.round(progress.bytesSent / progress.totalBytesToSend * 100);
// progress handling
});
}
Thanks for any help!
P.S. I also got a deprecated warning, although I'm not using group/TransferGroup on the BackgroundUploader class:
The method Windows.Networking.BackgroundTransfer.IBackgroundTransferBase.put_Group has been deprecated. Group may be altered or unavailable for releases after Windows 8.1. Instead, use TransferGroup.
Maybe it is related to that promise chain error.
Maybe a simple typo error ??
Just check the comments in codes below
var currentUpload; // global
function uploadFile(localFullPath, headers, serverUrl)
{
var fileUri = new Windows.Foundation.Uri('ms-appdata:///local' + localFullPath),
uploader = false;
try
{
uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();
uploader.method = 'PUT';
// set headers to uploader
for (var key in headers)
{
if (headers.hasOwnProperty(key))
uploader.setRequestHeader(key, headers[key]);
}
}
catch (e)
{
// error handling
return false;
}
/*
return something it's a good practice if you want to chain Promises
|
|
V */
return Windows.Storage.StorageFile.getFileFromApplicationUriAsync(fileUri)
.then(
function success(file){
return uploader.createUpload(serverUrl, file);
},
function failure(error){
return WinJS.Promise.wrapError('file not found');
// |_____________|
// your are rejecting your promise with ---------^
}
).then(
function (uploadOperation){
// Just avoid this type of code construction
// and add brace !
// adding brace augment readability and prevent errors !
// where do you set this ??? currentUpload = 'Canceled'
// is part of winjs ???
if (currentUpload == 'Canceled')
// why not handle your rejected promise ?
// by something like :
//if( uploadOperation == 'file not found' )
return WinJS.Promise.wrapError('upload canceled');
else
return ( currentUpload = uploadOperation.startAsync() );
}
).then(
// Promise resolve handler
function success(success){
currentUpload = false;
// success handling
return true;
} ,
// Promise reject handler
function failure(error){
currentUpload = false;
// error handling
return false;
}
/* ^
|
YOU HAVE HERE A DOUBLE CLOSING BRACE }} ???
°
| WHAT IS THIS PART FOR ??????
|
+------+---- Ending uploadFile with successive closing brace !
|
|+---------------- Declaration separator
|| +--- New function declaration
|| |
VV V */
}, function pending(status){
var progress = status.progress,
percent = Math.round(progress.bytesSent / progress.totalBytesToSend * 100);
// progress handling
});
}
/*
ALL THAT PART ABOVE IS NOT IN THE PROMISE CHAIN
AND SHOULD BREAK YOUR CODE !!!
HOW HAVE YOU EVER COULD RUN THIS ???
*/
maybe it miss a part of your code to be sure of that, because in this state your code must break !
Maybe an adjustement could be :
var currentUpload; // global
function uploadFile(localFullPath, headers, serverUrl)
{
var fileUri = new Windows.Foundation.Uri('ms-appdata:///local' + localFullPath),
uploader = false;
try
{
uploader = new Windows.Networking.BackgroundTransfer.BackgroundUploader();
uploader.method = 'PUT';
// set headers to uploader
for (var key in headers)
{
if (headers.hasOwnProperty(key))
uploader.setRequestHeader(key, headers[key]);
}
}
catch (e)
{
// error handling
return false;
}
/*
return something it's a good practice if you want to chain Promises
|
|
V */
return Windows.Storage.StorageFile.getFileFromApplicationUriAsync(fileUri)
.then(
function success(file){
return uploader.createUpload(serverUrl, file);
},
function failure(error){
return WinJS.Promise.wrapError('file not found');// O|--------+
}// |
).then(// |
function (uploadOperation){// O|-------------------------------|
// |
// Just avoid this type of code construction |
// and add brace ! |
// adding brace augment readability and prevent errors ! |
// |
// EDIT |
//if (currentUpload == 'Canceled') { // <--- add brace |
if (uploadOperation == 'file not found') { //<---add brace <--+
return WinJS.Promise.wrapError('upload canceled');
} else { // <---- add braces
// even if it is valid
// avoid assignement like that
// so subtil to read / understand / debug ...
// return ( currentUpload = uploadOperation.startAsync() );
currentUpload = uploadOperation.startAsync();
// maybe debug here ?
console.log('currentUpload : ' + currentUpload );
return currentUpload;
} // <---- add brace
}
).then(
function success(success){
currentUpload = false;
// success handling
return true;
} ,
function failure(error){
currentUpload = false;
// error handling
return false;
} ,
function pending(status){
var progress = status.progress,
percent = Math.round(progress.bytesSent / progress.totalBytesToSend * 100);
// progress handling
}
).done( // it is always a good thing to have a final catcher !!
function(){
// things are ok !
console.log('ok');
},
function(err){
// make something with your error better than
alert(err);
console.log('ko');
}
);
}
EDIT
Looking further (i do not use winjs), there is something to be clarified :
.then(
function success(file) {
return uploader.createUpload(serverUrl, file);
},
function failure(error) {
return WinJS.Promise.wrapError('file not found');
}
).then(
function(uploadOperation) {
if (currentUpload == 'Canceled')
return WinJS.Promise.wrapError('upload canceled');
else
return (currentUpload = uploadOperation.startAsync());
}
).
where are you setting this :currentUpload = 'Canceled'
You are checking that but i'am pretty sure this part of code is never reached.
Before that your reject your promise with :return WinJS.Promise.wrapError('file not found');
maybe the next then
should handle someting like that :
.then(
function success(file) {
return uploader.createUpload(serverUrl, file);
},
function failure(error) {
return WinJS.Promise.wrapError('file not found');
}
).then(
function(uploadOperation) {
if (uploadOperation == 'file not found')
return WinJS.Promise.wrapError('upload canceled');
else
return (currentUpload = uploadOperation.startAsync());
}
)
I hope this will help you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With