Can anyone figure out what is wrong with this code? I'm trying to write a small number of bytes to a file and all I get is a zero length file with no errors reported.
I'm trying to use async file IO and bluebird promises in node.js to write some data to a local file. I've successfully written a synchronous version of this function and an async version using callbacks. But, because the callback version was nested hell and had all sorts of error handling problems and was not very easy to maintain, I thought I'd try a version using promises instead since this should be its forte (better error handling, less nesting, easier to sequence async operations).
Unfortunately, the promise version only results in a zero length file. Here's the code for the promise version:
// at initialization time
var Promise = require('bluebird');
var fs = Promise.promisifyAll(require('fs'));
// code in a function
var header = new Buffer('[temperatures] {"formatVersion": "1", "fields": ["t", "atticTemp", "outsideTemp"]}\r\n');
filename += ".new";
console.log("async write started");
var fd;
fs.openAsync(filename, "w", 438).then(function(ffd) {
fd = ffd;
return fs.writeAsync(fd, header, 0, header.length, null);
}).then(function(args /* [written, buffer] */) {
var written = args[0];
console.log("bytes written =" + written);
if (written !== header.length) {
console.log("not all data written");
throw new Error("not all data written");
}
// lots more data to write here
return fs.closeAsync(fd);
}).then(function() {
fd = null;
console.log(" async write finished");
}).catch(function(e) {
// if (fd) fs.closeAsync(fd);
console.log(e, "data.writeData() - error writing data (new format)");
});
I've done everything I know how to do for debugging. All expected console.log()
error messages appear in the desired order. I've verified all return values and arguments along the way. No errors are reported in any way. I've removed the previous file before running it again. I'm using the same arguments and filename in my callback version that works just fine (which seems to rule out a file permission issue). I've rebooted the computer (which is a Raspberry Pi, by the way).
I'm stumped. I assume this must be something silly I'm doing wrong in my use of promises, but I can't for the life of me see what's wrong.
OK, I figured it out. This function works perfectly fine when it is called in the normal operation of the app. And, if I look at the file that it generates while the app is still running, the file is fine.
But (and this is where the problem occurs), I'm also calling this function when the app exits. And, guess what, you can't use these types of async operations in an exit event handler without causing problems. It gets as far as creating the new empty file and then the app exits and that's where things are left (just the newly created empty file on disk).
This particular function has an argument passed in for whether the writing needs to be done sync or async (just for this reason) and I hadn't yet written the sync portion of the new promise style code (I had written the sync version of the other versions of the code I had used).
Odd mystery solved. And, it was something silly. Nothing directly to do with promises, but it was an async issue.
One other mystery is why the version of my code that was async, but used callbacks instead of promises did not show this issue? Apparently, it finished it's job before the process exited, but the promise version didn't.