1

In node.js asynchronous functions have callback, however only some of them have err argument passed to that function. e.g. fs.writeFile has err as parameter

fs.writeFile('message.txt', 'Hello Node', function (err) {
  if (err) throw err;
  console.log('It\'s saved!');
});

but fs.watchfile doesn't

fs.watchFile('message.text', function (curr, prev) {
  console.log('the current mtime is: ' + curr.mtime);
  console.log('the previous mtime was: ' + prev.mtime);
});

First question is why some async functions have err argument in callback and some don't? How are we supposed to handle error of those which don't?

Also, as far as synchronous functions are concerned, are they all emitting "error" event which we can subscribe to and handle error this way?

var rs = fs.createReadStream("C:\\Temp\\movie.mp4"); 
    rs.on('error', function(err) {
        console.log('!error: ', err);
    });

and last question: most of synchronous functions have Sync in name... why createReadStream does not?

Thanks!

1 Answer 1

5

First question is why some async functions have err argument in callback and some don't? How are we supposed to handle error of those which don't?

The vast majority of asynchronous functions in node code conform to the convention of the first argument to the callback function is the error. There are a very small number of exceptions, such as fs.exists, which is clearly documented as an antipattern that should not be used in the official docs.

In the case of watchFile in particular, it's just the semantics of the API that it calls the callback repeatedly and only on success just because that's what it means to watch a file and in general the OSes don't provide a mechanism that has the semantic "notify me when anything goes wrong with this filesystem path", so there you have it.

Also, as far as synchronous functions are concerned, are they all emitting "error" event which we can subscribe to and handle error this way?

No. Your categorization of node mechanics is incomplete. There are at least 4 major paradigms:

  • synchronous code. Mostly throws exceptions to indicate errors like JSON.parse but not always. For example, parseInt returns NaN to indicate an error.
  • asynchronous code in callback style. Generally passes an error as the first argument to the callback.
  • asynchronous code in the event emitter/streaming style. Generally emits an "error" event.
  • asynchronous code using promises. Not used in node core but has a large and loyal set of devotees in the community. Generally rejects the promise via invoking the "reject" callback which is the second argument passed to .then.

most of synchronous functions have Sync in name... why createReadStream does not?

Because it's not really synchronous. It's event emitter based streaming. The actual createReadStream will synchronously return you the stream object, but the I/O is asynchronous and events won't start to be emitted until the next tick at the earliest.

I highly recommend the article Error Handling in Node.js on the joyent blog for the current best practices described thoroughly.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks! what's the best way to figure out whether we deal with async function in event emitter style (i.e. it emits "error" event)? documentation for createReadStream does not seem to mention it: nodejs.org/api/fs.html#fs_fs_createreadstream_path_options and from what I know there's no way to know it programatically
Anything called "stream" will be an event emitter. But yes, generally you read the docs and you can't know an event based API programmatically just like you can't programmatically determine the semantics of a function's arguments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.