14 Aug 2014, 04:25
Generic-user-small

Todd Decker (7 posts)

I’m trying to handle the issues discussed in the “Fortifying Code” section of “Wrangling the File System”. I also want to “catch” the errors so that I can show a nice message instead of the normal dump. I know that I cannot use a try-catch within the async part of the code (it works outside of that block). So, I’m having trouble figuring out how to catch the event that occurs when the file being watched is moved for deleted. I can trap the error and throw a new Error, but I cannot seem to figure out how to handle it properly with a callback. I’d sure appreciate a hint.

Here is what I have so far (and it’s on GitHub too):

#!/usr/bin/nodejs --harmony
/*
 * Exemplifies watching a file for changes then spawning a separate
 * process to execute a shell function and process its subsequent
 * output stream.
 *
 * c.f. "Node.js The Right Way", by Jim R. Wilson
 */

"use strict";

const
    fs = require('fs'),
    spawn = require('child_process').spawn,
    filename = process.argv[2];

try {

    if (!filename) {
     throw Error("A file to watch must be specified!");
    }

    if (!fs.existsSync(filename)) {
        throw Error("'" + filename + "' does not exist!");
    }

    fs.watch(filename, function() {

        let ls = spawn('ls', ['-lh', filename]),
            output = '';

        ls.stdout.on('data', function(chunk) {
            output += chunk.toString();
        });

        ls.on('close', function() {
            if (output.length == 0) {
                throw Error("The watched file ('" + filename + "') has been moved or deleted!");
            }
            let parts = output.split(/\s+/);
            console.dir([parts[0], parts[4], parts[8]]);
        });

    });

    console.log("Now watching '" + filename + "' for changes...");

} catch(err) {
    console.log(err.message);
}

05 Sep 2014, 21:01
Avatar_pragsmall

Jim R. Wilson (68 posts)

Hi Todd,

Did you figure out how to handle the Error or are you still looking for help?

10 May 2015, 01:28
Generic-user-small

Michael Cox (1 post)

Is this what you’d have in mind for the fs.watch error handling for this exercise?

fs.watch returns an fs.FSWatcher, which is an EventEmitter. Using that, we can emit an ‘error’ event to pass errors out of the watch function:

var fswatcher = fs.watch(filename, function(event, filename) {
	if (event === 'rename'){
		this.emit('error', new Error('file has been renamed'));
	}
	else if (event === 'change'){
		let ls = spawn('ls', ['-lh', filename]),
			output = '';
		ls.stdout.on('data', function(chunk) {
			output += chunk.toString();
		});

		ls.on('close', function() {
			let parts = output.split(/\s+/);
			console.dir([parts[0], parts[4], parts[8]]);
		});
	}
});

fswatcher.on('error', function(err){ console.log('fswatcher error: ' + err.message)});
  You must be logged in to comment