How to handle errors between internal server API and HTTP API

This is how my node.js server is organised

organisation

Problem: The API makes requests to my mongodb database via the model (mongoose). So in the API layer I can have:

User.findById(id, function(user) {
   if(user._id !== userid) return deferred.reject(new Error()); // ??
   if(!user) return deferred.reject(new Error()); // ??
   user[field] = value;
   user.save(function() {
    deferred.resolve(user);
   }); 
});

But what errors should I throw? What way would be more proper and more user-friendly. I could try for example:

   if(user._id !== userid) return deferred.reject(new Error(403));

But that would mean no message, just the error code :/

Another solution i tried:

exports.errors = errors =

  NOT_FOUND:
    id: "NOT_FOUND"
    code: 404
    message: "Can't found requested object. Please retry"
  UNAUTHORIZED:
    id: "UNAUTHORIZED"
    code: 401
    message: "Please login first"
  FORBIDDEN:
    id: "FORBIDDEN"
    code: 403
    message: "Access denied."
  DATABASE_ERROR:
    id: "DATABASE_ERROR"
    code: 500
    message: "Error with databse. Please retry"

exports.throwError = throwError = (message, id) ->
  if typeof message is "string" then err = new Error message else err = message
  err.type = id
  err.data = errors[id]
  return err

exports.handleHttp = (err, req, res, format="text") ->
  console.log("   Error - #{err.message} (#{err.type}) on #{req.url}".red)
  console.log(err.stack)
  if format is "text"
    res.send err.data.code, "#{err.data.type}: #{err.message}"
  if format is "json"
    res.send err.data.code,
      type: err.data.type
      message: err.message
      id: err.type
      status: "error"
      errors: err.errors

And so I would use it like that:

   if(user._id !== userid) return deferred.reject(error.throwError("Forbidden", "UNAUTHORIZED"));

And in the controller (after a promise)

.fail (err)->
    errors.handleHttp err, req, res, "json"

But I don't like this solution, this leaves me with a bitter feeling, unsatisfied. Any other idea?

You can define new Error objects that extend the existing Error object. For example, the following would be for a 404 error:

function HttpError(message, code) {
    this.message = message || "";
    this.code = code || 500;
}

HttpError.prototype = Object.create(Error.prototype);

HttpError.prototype.send = function send(req, res) {
    var type = req.accepts("json", "html", "text");

    switch(type) {
        case "json":
            res.send(this.code, JSON.stringify(this));
        break;

        case "html":
        case "text":
            res.send(this.code, "An error occurred: " + this.message);
        break;
    }
};

function NotFoundError(message, code) {
    this.name = "NotFound";
    this.message = message || "Could not find the object you were requesting";
    this.code = code || 404;
}
NotFoundError.prototype = Object.create(HttpError.prototype);

You can then use it like so:

User.findById(id, function(user) {
   if(!user) return deferred.reject(new NotFoundError());

   user[field] = value;
   user.save(function() {
    deferred.resolve(user);
   }); 
});

You can place all of the errors (500, 404, 401, etc.) in an errors file and include that. So it would likely be new errors.NotFoundError();

Then, in your controller you can have a fail callback function like so:

getUser().fail(function(err) { err.send(req, res) });

This will only work if err is an instance of the HttpError class.