What is the more correct position for the error argument in a javascript callback?

Problem

I am writing a javascript function that takes a callback. The callback will be passed an error argument if something goes wrong.

What are the best / most standard calling conventions?

  • Should the callback’s error argument be first or last?
  • Should I pass an 'errorMsg' string, or a new Error('errorMsg') object?

Ie, what is more correct — this code:

foo = function(bar, callback) {
...
if (error) {
callback('troz not found');
} else {
callback(null, result);
}
}

or this code:

foo = function(bar, callback) {
...
if (error) {
callback(null, 'troz not found');
} else {
callback(result);
}
}

or this:

foo = function(bar, callback) {
...
if (error) {
callback(null, new Error('troz not found'));
} else {
callback(result);
}
}

If its relevant, my code will be used as both as a NodeJS module and as a browser-based javascript library.

Problem courtesy of: Joseph

Solution

You should choose a convention for your library and stick with it; otherwise, it is arbitrary. There are many different ways of handling errors in JavaScript:

  1. Taking both a “success” and “error” callback.
  2. Taking a single callback to handle both “success” and “error” cases.
  3. Having a registration mechanism for a default “error” handler, making error handlers optional on all other calls, using the immediate or fallback error callbacks as appropriate.

Combined with:

  1. Using no parameters to the error callback.
  2. Using a boolean to indicate success / failure.
  3. Using a string to encapsulate the nature of the error.
  4. Using some more complex “Result” object to encapsulate success/failure and the result.
  5. Using some complex object to encapsulate detailed failure information.

Really, it’s entirely up to you. It also depends on what you are trying to do. For example, if you don’t really intend to do anything with the failure information, then it might not be worth the expense of constructing / passing around that extra information. But perhaps you have lots of detailed failure information you want to pass to the user or back to the API caller, in which case it makes lots of sense.

Choose a convention, and stick with it. Other than that, it’s entirely up to you.

Solution courtesy of: Michael Aaron Safyan

View additional discussion.