small medium large xlarge

Generic-user-small
14 Aug 2014, 04:25
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);
}

Avatar_pragsmall
05 Sep 2014, 21:01
Jim R. Wilson (69 posts)

Hi Todd,

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

Generic-user-small
10 May 2015, 01:28
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