Reputation: 258
I have code like this for logging in my WinJS app:
function setupFileLog() {
var logFn = function (message, tag, type) {
if (!log_file) return; // log_file is global, setup below with a StorageFile object
Windows.Storage.FileIO.appendTextAsync(log_file, tag + ' ' + type + ': ' + message)
.done(null, function (error) {
// I have a breakpoint here to catch the error
var msg = error.detail.message;
}
});
};
app_folder.createFolderAsync('logs', Windows.Storage.CreationCollisionOption.openIfExists)
.then(function (logfolder) {
var now = new Date();
var logfilename = config.device + "_" + now.toDateString() + ".log";
return logfolder.createFileAsync(logfilename, Windows.Storage.CreationCollisionOption.openIfExists)
})
.done(function (file) {
log_file = file; // save in global var
WinJS.Utilities.startLog({ tags: "myApp", action: logFn });
});
}
setupFileLog();
// ...
// do stuff and log things
// ...
WinJS.log && WinJS.log('I did some stuff', 'myApp','info');
WinJS.log && WinJS.log('I got an error: '+error, 'myApp','error');
Intermittently, I get an error in my logFn "The process cannot access the file because it is in use by another process" or "Access is denied". I think that multiple calls to WinJS.log are colliding because of the async nature of the appendText call and trying to get a handle to the log file before the previous logging call is finished writing.
Can I make appendTextAsync wait until the log file is not in use? I can't find any calls to check if the file is busy. I think there is a way to make appendTextAsync act in a synchronous way but I'd like to avoid doing that in all cases since this is just an intermittent case.
Upvotes: 0
Views: 473
Reputation: 665100
You could make a chain of calls that is automatically executed in sequence:
function setupFileLog() {
var log_file = app_folder.createFolderAsync('logs', Windows.Storage.CreationCollisionOption.openIfExists)
.then(function (logfolder) {
var now = new Date();
var logfilename = config.device + "_" + now.toDateString() + ".log";
return logfolder.createFileAsync(logfilename, Windows.Storage.CreationCollisionOption.openIfExists)
});
WinJS.Utilities.startLog({
tags: "myApp",
action: function log_fn(message, tag, type) {
log_file = log_file.then(function(file) {
return Windows.Storage.FileIO.appendTextAsync(file, tag + ' ' + type + ': ' + message)
.then(function() {
return file;
}, function (error) {
// I have a breakpoint here to catch the error
var msg = error.detail.message;
return file; // for further logs, or
throw error; // go stop logging
});
});
}
});
}
Every call to the log_fn
does chain another appendTextAsync
call onto the log_file
promise. The bonus is that calls are already chained when the log file is not yet created, instead of simply dropping log lines.
Upvotes: 3